非常简单的情况。不知道为什么会导致问题。
我有一个视图,在子NSManagedObjectContext中创建一个新的NSManagedObject。当用户按下“完成”时,它保存子上下文,然后保存父上下文,然后使用新创建的对象的objectID发布通知。在主视图控制器中,我响应通知并尝试使用existingObjectWithID:error:
获取新创建的对象。
问题是失败,因为objectID是临时的(我得到了“Cocoa错误133000”)。保存到两个上下文是完美的:当我重新加载应用程序时,我可以看到我创建的条目。但是当我需要获得对新对象的引用时,它失败了。
为什么在我已经保存后,它会给我一个临时的对象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;
}
}
答案 0 :(得分:11)
因为孩子没有从父母MOC获得更新。父MOC将使用永久ID更新其自己的NSManagedObject
实例,但该更改不会被推送到属于子MOC的NSManagedObject
实例。
在这种情况下我不使用-objectID
。它有一些用途,但它不是永久的唯一ID。在这种情况下,我更喜欢将自己的uniqueID添加到实体中,然后从主上下文中获取它。
您也可以只是监听上下文保存通知或使用将接收更新的NSFetchedResultsController。
答案 1 :(得分:9)
您是否尝试获取对象的永久ID?我通过调用
成功地在上下文之间共享NSManagedObjectID
NSError *error = nil;
[self.context obtainPermanentIDsForObjects:@[object1, object2]
error:&error];
后面是我的保存方法。我以这样的方式构造我的上下文,即有一个I / O上下文,它是我的'读取上下文'(用于我的主线程活动的上下文)的父级,它是我的后台任务上下文的父级。在这种情况下保存一直向上传播。