即使保存之后,新创build的NSManagedObject也会返回临时的objectID

非常简单的情况。 不知道为什么这是一个问题。

我有一个视图,在子NSManagedObjectContext中创build一个新的NSManagedObject。 当用户按下“完成”时,它保存子上下文,然后保存父上下文,然后用新创build的对象的对象ID发布通知。 在主视图控制器中,我响应通知并尝试使用existingObjectWithID:error:获取新创build的对象existingObjectWithID:error:

问题是这个失败,因为objectID是临时的(我得到一个“cocoa错误133000”)。 保存到两个上下文是完美的:当我重新加载应用程序,我可以看到我创build的条目。 但是当时我需要得到一个新的对象的引用,它失败了。

为什么我已经保存后为它提供了一个临时的对象ID?

注意:我已经尝试过使用obtainPermanentIDsForObjects:error:它可以工作,但是当我尝试使用它来获取对象时,永久ID仍然失败。

这是一些代码:

 -(IBAction)done:(id)sender { if ([editorDoneNotification isEqualToString:kNOTIFICATION_OBJECTADDED]) { // save the temporary moc NSError* e; if (![self.tempContext save:&e]) { // this is always a successful save NSLog(@"Failed to save temporary managed object context: %@", [e localizedDescription]); [[[UIAlertView alloc] initWithTitle:@"Database Error" message:@"Failed to add object." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; } } NSError* e; if (![[[AMDataModel sharedDataModel] mainContext] save:&e]) { // this is also successful NSLog(@"Failed to save main managed object context: %@", [e localizedDescription]); [[[UIAlertView alloc] initWithTitle:@"Database Error" message:@"Failed to edit object." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; } else [[NSNotificationCenter defaultCenter] postNotificationName:editorDoneNotification object:[self.editingObject objectID]]; [self.navigationController dismissViewControllerAnimated:YES completion:nil]; } 

这就是我对通知的回应:

 -(void)objectAdded:(NSNotification*)notification { if (self.popoverController && [self.popoverController isPopoverVisible]) { [self.popoverController dismissPopoverAnimated:YES]; } NSManagedObjectID* newObjectID = (NSManagedObjectID*)(notification.object); NSError* error; AMObject* object = (AMObject*)[[[AMDataModel sharedDataModel] mainContext] existingObjectWithID:newObjectID error:&error]; // this is where the cocoa error 133000 happens if (error != nil) { NSLog(@"ERROR: Could not load new object in main managed object context."); } GMSMarker* m = [[GMSMarker alloc] init]; m.position = CLLocationCoordinate2DMake(object.latitudeValue, object.longitudeValue); m.userData = object; m.map = self.mapView; [self.markers addObject:m]; } -(void)objectEdited:(NSNotification *)notification { NSManagedObjectID* editedObjectID = (NSManagedObjectID*)notification.object; NSError* error = nil; AMObject* object = (AMObject*)[[[AMDataModel sharedDataModel] mainContext] existingObjectWithID:editedObjectID error:&error]; if (error != nil) { NSLog(@"Error could not load edited object in main managed object context"); } //update the UI based on edit if ([self.popoverController isPopoverVisible]) { [self.popoverController dismissPopoverAnimated:YES]; self.popoverController = nil; } } 

因为孩子没有从母校转回。 父MOC将使用永久ID更新自己的NSManagedObject实例,但该更改不会被下推到属于子MOC的NSManagedObject的实例。

更新1

在这种情况下,我不使用-objectID 。 它有一些用途,但它不是一个永久的uniqueID。 在这样的情况下,我更愿意将自己的uniqueID添加到实体中,然后从主要上下文中获取它。

您也可以只听上下文保存通知或使用NSFetchedResultsController将接收更新。

你有没有试图获得你的对象的永久ID? 我已经成功地通过调用在上下文之间共享NSManagedObjectID

 NSError *error = nil; [self.context obtainPermanentIDsForObjects:@[object1, object2] error:&error]; 

其次是我的保存方法。 我以这样的方式构build我的上下文,即有一个I / O上下文,它是我的“读取上下文”(用于我的主线程活动的上下文)的父级,这是我的后台任务上下文的父级。 保存在这种情况下传播一路上。