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

Shi*_*ami 15 core-data objective-c ios

非常简单的情况.不知道为什么会导致问题.

我有一个视图,在子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];
}
Run Code Online (Sandbox Code Playgroud)

这就是我回复通知的方式:

-(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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*rra 12

因为孩子没有从父母MOC获得更新.父MOC将NSManagedObject使用永久ID 更新其自己的实例,但该更改不会被推送到NSManagedObject属于子MOC 的实例.

更新1

我没有-objectID在这种情况下使用.它有一些用途,但它不是永久的唯一ID.在这种情况下,我更喜欢将自己的uniqueID添加到实体中,然后从主上下文中获取它.

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


Nat*_*nes 9

您是否尝试获取对象的永久ID?我NSManagedObjectID通过打电话在上下文之间分享了成功

NSError *error = nil;
[self.context obtainPermanentIDsForObjects:@[object1, object2]
                                     error:&error];
Run Code Online (Sandbox Code Playgroud)

然后是我的保存方法.我以这样的方式构造我的上下文,即有一个I/O上下文,它是我的'读取上下文'(用于我的主线程活动的上下文)的父级,它是我的后台任务上下文的父级.在这种情况下保存传播到链的所有方向.

  • 将"nil"传递给错误是一件坏事.它隐藏了让你挠头的错误.始终始终检查错误. (2认同)