插入到 FetchResultsController 后如何获取 NSManagedObject ObjectID (objectID.isTemporaryID==NO)?

How to get NSManagedObject ObjectID (objectID.isTemporaryID==NO) after insert to FetchResultsController?

我正在使用 CoreData,我想在 insert/saved 新的 NSManagedObject 进入上下文后获得一个 objectID(不是临时的)。

在我的介绍中 vc 保存:

NSManagedObjectContext *context = ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
EventMO *newEvent = [NSEntityDescription insertNewObjectForEntityForName:@"EventMO" inManagedObjectContext:context];            
if ([context save:&error]) {
    [self dismissViewControllerAnimated:YES completion:nil];
}

在我使用 fetchResultViewController 和 tableView 的主视图控制器中,我在哪里可以获得新保存的 NSmanagedObject 对象 ID,即 objectID.isTemporaryID==NO

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [[self tableView] endUpdates];
}

- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller{
    [[self tableView] beginUpdates];
}

我在 [[self tableView] endUpdates]; 之后尝试了 [_fetchedResultsController objectAtIndexPath:newPath];,但似乎不起作用。错误:

po [self.fetchedResultsController objectAtIndexPath:_insertedIndexPath]
error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3)..
The process has been returned to the state before expression evaluation.

我也不确定在 endUpdates 后 isTemporaryID 是否为 NO。

编辑

    - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
...
   EventMO *event   = [_fetchedResultsController objectAtIndexPath:indexPath];
   if (!event.objectID.isTemporaryID) {
        Event *e = [Event new];
        e.eventID = event.objectID;
    }else{
      //It will get into this even after "save" method. Why?
      NSLog(@"This is temporary id");
    }
   ...
}

我想这里(结束更新后)应该不是临时ID,我想通过以下方式检查它:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
        [[self tableView] endUpdates];
EventMO *event   = [_fetchedResultsController objectAtIndexPath:indexPath];
//po this event, get the error below
    }

我收到了错误。

error: Execution was interrupted, reason: internal ObjC exception breakpoint(-3)..
The process has been returned to the state before expression evaluation.

编辑 2 我有下面两个 类:

@interface Event : NSObject
@interface EventMO : NSManagedObject

我的 UITableViewCell 子类只有一个 属性 事件:

@interface CountCell : UITableViewCell
@property (nonatomic, strong) Event *event;
@end

我的 tableView 取决于用户是否注册。如果已注册,则应使用Event,否则核心数据应在本地使用EventMO。所以在创建并保存了一个新的 EventMO 之后,我需要 CountCell 来显示它。所以我必须从 EventMO 转换为 Event 才能显示它。

保存后,您将获得一个持久对象 ID...除非您没有直接连接到 PSC,而是有一个父 MOC。

基本上,从直接连接到 PSC 的 MOC 保存时,您只会获得持久对象 ID。

但是,您可以随时使用 NSManagedObjectContext 方法

转换为持久对象 ID
- (BOOL)obtainPermanentIDsForObjects:(NSArray *)objects
                               error:(NSError **)error;

编辑

首先,如果您的代码依赖于知道对象 ID 是否是临时的,您应该重新考虑您的逻辑...这听起来不对,除非您正在编写一些特殊的核心数据代码。

其次,如果您的 MOC 有一个 PSC 而不是一个父 MOC,您必须在保存上下文之前查询 objectID 和它的 temp/perm 状态。为什么不在保存上下文的地方做这样的事情...

NSLog(@"before save: %@", [moc registeredObjects]);
BOOL result = [moc save:&error];
NSLog(@"after save: %@", [moc registeredObjects]);

您将看到所有对象的 ID...您可以直观地区分临时对象和永久对象。

临时的长这样...

<NSManagedObject: 0x7f8834836e10> (
  entity: Foo;
  id: 0x7f8834836e70 <x-coredata:///Foo/tECDD46E2-3D01-4E5D-BCE8-1DD8DB2138A512>;
  data: { identifier = 8; }),

永久的长这样...

<NSManagedObject: 0x7f8834836e10> (
  entity: Foo;
  id: 0x7f8834c231e0 <x-coredata://38B5921E-4638-42FD-AD94-78555561DBA7/Foo/p2>;
  data: { identifier = 8; }),

保存后,所有对象都应具有永久 ID。

请记住,只要 MOC 发生变化,FRC 就会得到更新,而不仅仅是在发生保存时。

您在问题末尾引用的异常看起来像一个错误的 indexPath。