iOS Core Data何时保存上下文? [英] iOS Core Data when to save context?

查看:150
本文介绍了iOS Core Data何时保存上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于并发和多线程,我正在与核心数据发生随机崩溃。我知道核心数据不是线程安全的。我还发现了一些其他答案如何创建一个ThreadedDataService和实例化每个线程的单独上下文。

I'm having random crashes with core data due to concurrency and multithreading. I know that core data is not thread safe. I also found a couple other answers on how to create a ThreadedDataService and instantiate separate context for each thread.

这对我来说太累了,所以我想找一个更简单的方法。

This is a bit too much for me to swallow at the moment, so I'm trying to find an easier way out.

我现在尝试的解决方案很简单:通过主线程保存数据。但是,现在出现了一个新问题: deadlock 。该应用程序变得无响应,因为我的每次插入一个新的NSManagedObject后面是一个调用保存。 (这是我最好的猜测)。

The solution that I'm trying at the moment is simple: saving data through the main thread. However, now a new issue arises: deadlock. The app becomes unresponsive because each of my insertions of a new NSManagedObject is followed by a call to save. (that's my best guess).

阅读App Delegate文档,我注意到它建议我在applicationWillTerminate中保存上下文。

Reading the App Delegate documentation, I noticed that it advises me to save context in applicationWillTerminate.

我的问题是这样:对于长时间运行的操作,每分钟插入新事件,并且用户不需要立即看到传播到所有控制器的更新,什么时候是我节省的好时机上下文?
我得到一个感觉,每个记录的保存上下文可能是过度的?

My question is this: For a long running operation that inserts new events every minute, and the user is not required to see updates propagated to all controllers immediately, when is it a good time for me to save the context? I'm getting a feeling that saving context for each record may be an overkill?

-(void)insertNewEvent
{


    // Create a new instance of the entity managed by the fetched results controller.
    NSManagedObjectContext *context = [self.fetchedResultsController.managedObjectContext];
    NSEntityDescription *entity = [[self.fetchedResultsControllerfetchRequest] entity];
    Event*newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

//use accessor methods to set default values

    // Save the context. > IS THIS REALLY NEEDED HERE?
    NSError *error = nil;
    if (![context save:&error])
    {


    }else
    {
        if(newManagedObject!=nil)
        {
            currentState= newManagedObject;
            [currentRecord addEvent:newManagedObject];
//Is this call needed?
            [self saveApplicationRecords];      
        }
    }

}



如果我在主线程上每隔10-15分钟调用这样的方法来保存挂起的更改,而不是在每个记录插入之后这样做,就足够了?

I have methods like these defined for all of my managed objects, is it enough if I call such method on a main thread every 10-15 minutes to save pending changes, rather than doing so after each record insertion?

-(void)saveApplicationRecords
{
     NSLog(@"saveApplicationRecords");
    NSManagedObjectContext *context = [self.applicationRecordsController.managedObjectContext];
    // Save the context.
    NSError *error = nil;
    if (![context save:&error])
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

    }

}

-(Event*)insertAndReturnNewEventWithDate:(NSDate*)date_ type:(int)type
{
 NSManagedObjectContext *context = [self.dreamEventsController managedObjectContext];
    NSEntityDescription *entity = [[self.dreamEventsController fetchRequest] entity];
    DreamEvent *newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

//handle properties

 NSError *error = nil;
    if (![context save:&error])
    {
return nil;

    }else
    {
return newManagedObject ;
}

}

谢谢!

推荐答案

你不必在过程的早期保存上下文,特别是当你想修改对象时。

You don't have to save the context that early in the process, especially when you want to modify the object afterwards.

在大多数情况下,您应该为您要对数据库执行的更改创建一个单独的 NSManagedObjectContext 。因此,在其上创建对象,填写所需的属性,然后发送 save 并执行整个 mergeChangesFromContextDidSaveNotification:主上下文(很可能在主线程上运行,因此使用 performSelectorOnMainThread ...消息)。

In most cases you should create a separate NSManagedObjectContext for the changes you're about to perform on the database. So create objects on it, fill out the properties needed, then send save and perform the whole mergeChangesFromContextDidSaveNotification: trick with the main context (most likely running on the main thread, so using performSelectorOnMainThread... message).

NSManagedObjectContext 创建和返回的对象将被自动释放。例如,如果您创建了一个新对象并希望在表单工作表中进行编辑,则可以在创建对象之前,对托管对象上下文调用 setRetainsRegisteredObjects:所以它坚持到创建的对象,直到你完成它。记住,不建议自己管理 NSManagedObject 的生命周期 - 你应该让 NSManagedObjectContext 这样做。所以,记住这一点,你不必保留 NSManagedObject 。保存操作后,它从上下文注销并从内存中删除。

By default an object created and returned by NSManagedObjectContext is autoreleased. If you've created a new object and want to edit it in a form sheet for example, you can call setRetainsRegisteredObjects: with YES to the managed object context before creating the object, so it holds on to the object created until you're done with it. Remember that it's not recommended to manage the NSManagedObjects' lifecycle on your own - you should let the NSManagedObjectContext do it. So, having that in mind, you don't have to retain the NSManagedObject. After the save operation it's unregistered by the context and removed from memory. Nothing is required on your side.

NSManagedObjectID (使用 [object objectID] ),而不是对象本身。它允许通过上下文安全地处置对象,并且如果需要对象进一步编辑或数据检索(例如从其他上下文),则它们可以单独从商店获取它们。

It would be probably better if you returned an NSManagedObjectID (using [object objectID]) instead of the object itself. It allows to safely dispose of the object by the context and if one needs the object for further editing or data retrieval (e.g. from other contexts), they can fetch it from the store separately.

即使不保存上下文,新创建的对象也在那里,然后您可以决定是否要保留对象。

Even if you don't save the context, the newly created object is there and then you can decide if you want to keep the object or not.

另一方面,保存后,如果上下文仍然存在,它可以从内存缓存中返回给定 NSManagedObjectID 的对象 - 而不用触及数据库。

After saving on the other hand, if the context still exists, it may return the object with given NSManagedObjectID to you from memory cache - without touching the database.

另一方面,在你的情况下,你几乎可以安全地返回对象,因为 NSManagedObjectContext 创建它仍然存在,所以对象仍然存在,虽然已经在autorelease池。

On yet another hand ;), in your case, you can pretty much safely return the object, since the NSManagedObjectContext creating it still exists, so the object will still exist as well, although already in the autorelease pool.

这篇关于iOS Core Data何时保存上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆