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

时间:2015-02-21 08:18:36

标签: core-data

我正在使用CoreData,我希望在将新的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];
}

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

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

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

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

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是否。

修改

    - (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");
    }
   ...
}

我猜这里(在endupdates之后)不应该是临时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才能显示它。

1 个答案:

答案 0 :(得分:0)

保存后,您将获得持久对象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。

请记住,FRC将在MOC更改时随时获取更新,而不仅仅是在保存发生时。

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