iphone - CoreData 和 mergeChangesFromContextDidSaveNotification

标签 iphone core-data

我正在创建一个addingManagedObjectContext 作为新实体的便笺簿区域,然后在“保存”时将新实体合并到我的主 ManagedObjectContext 中,类似于 CoreDataBooks 示例中的显示方式。

合并新实体后,如何快速引用它以用于显示详细 View ?

您是否必须使获取结果 Controller 退出并再次执行获取(如 CoreDataBooks 代码中所述,昂贵)?我假设对象在“addingManagedObjectContext”中的初始 id 在合并后不会保持不变。

在 Recipes 项目中,不存在这种问题,因为您正在一个 ManagedObjectContext 中创建和使用新实体。因此,您可以引用新创建的项目来显示其详细 View 。

来自 CoreDataBooks:

/**
 Add controller's delegate method; informs the delegate that the add operation has completed, and indicates 
 whether the user saved the new book.
 */
- (void)addViewController:(AddViewController *)controller didFinishWithSave:(BOOL)save {

    if (save) {
        /*
         The new book is associated with the add controller's managed object context.
         This is good because it means that any edits that are made don't affect the 
         application's main managed object context -- it's a way of keeping disjoint edits 
         in a separate scratchpad -- but it does make it more difficult to get the new book 
         registered with the fetched results controller.

         First, you have to save the new book.  This means it will be added to the persistent 
         store.  Then you can retrieve a corresponding managed object into the application 
         delegate's context.  Normally you might do this using a fetch or using objectWithID: -- for example

         NSManagedObjectID *newBookID = [controller.book objectID];
         NSManagedObject *newBook = [applicationContext objectWithID:newBookID];

         These techniques, though, won't update the fetch results controller, which 
         only observes change notifications in its context.

         You don't want to tell the fetch result controller to perform its fetch again 
         because this is an expensive operation.

         You can, though, update the main context using mergeChangesFromContextDidSaveNotification: which 
         will emit change notifications that the fetch results controller will observe.
         To do this:
         1  Register as an observer of the add controller's change notifications
         2  Perform the save
         3  In the notification method (addControllerContextDidSave:), merge the changes
         4  Unregister as an observer
         */
        NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
        [dnc addObserver:self selector:@selector(addControllerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];

        NSError *error;
        if (![addingManagedObjectContext save:&error]) {
            // Update to handle the error appropriately.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            exit(-1);  // Fail
        }
        [dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:addingManagedObjectContext];
    }
    // Release the adding managed object context.
    self.addingManagedObjectContext = nil;

    // Dismiss the modal view to return to the main list
    [self dismissModalViewControllerAnimated:YES];
}


/**
 Notification from the add controller's context's save operation. This is used to update the 
 fetched results controller's managed object context with the new book instead of performing 
 a fetch (which would be a much more computationally expensive operation).
 */
- (void)addControllerContextDidSave:(NSNotification*)saveNotification {

    NSLog(@"addControllerContextDidSave");
    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
    // Merging changes causes the fetched results controller to update its results
    [context mergeChangesFromContextDidSaveNotification:saveNotification];  
}

最佳答案

看看这些评论,看起来他们正在谈论获取结果 Controller 。因此,在您刚刚更改一个对象后,让 FRC 执行新的获取会相当昂贵,因此您可以将添加上下文与其合并以通知它任何更改。

执行保存和合并后,您在添加上下文中引用的任何托管对象将不再具有临时对象 ID,因为它们存在于持久存储中。因此,您可以记住 ID 并在主应用程序上下文中使用 [applicationContext objectWithID:newBookID] 就可以很好地获取您正在查找的对象的句柄。这将返回应用程序上下文中的对象(及其所有更改)。

合并后,该对象很可能存在于内存中,无需访问存储。然而,即使是这样,因为您只处理要在详细 View 中显示的单个对象,所以根本不是问题。访问存储而不是上下文内存速度较慢,但​​显然必须在应用程序期间发生很多次,并且除非您处理大量数据,否则不太可能导致问题!

希望这有帮助!

关于iphone - CoreData 和 mergeChangesFromContextDidSaveNotification,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1429900/

相关文章:

iphone - 向核心数据实体添加属性

objective-c - 何时需要将 NSManagedObjectContext 与 NSMainQueueConcurrencyType 一起使用

iphone - 我如何将 UIFont 转换为 CGFontRef?我会导致警告并且无法工作

iphone - 如何在 Xcode 中一次在多个目的地上 'Build & Run'?

iphone - 在 iphone Sdk 上允许在我的应用程序中自动锁定

objective-c - 重命名 NSManagedObject 类中的核心数据属性

ios - swift 中 AppDelegate 和 Context 的作用是什么?

ios - 为什么 NSFetchedResultsController 的 fetchedObjects 数组并不总是同质的

ios - 核心数据关系 - 两个实体对一个实体

在沙盒模式下重新启动后找不到 iOS 7 应用收据