如何从NSManagedObjectContext中删除新对象

时间:2012-04-03 04:41:09

标签: objective-c nsmanagedobject restkit nsmanagedobjectcontext

好的,让我们从代码开始吧。我循环遍历返回的字典数组并基于它们创建(或更新)对象。在这个方法中,我正在尝试查找或创建一个新实体。然后,如果该对象应该被删除,我想这样做,而不是浪费时间用新信息更新它。

- (void)updateOrCreateObjectWith:(NSDictionary*)dictionary {
    RKManagedObjectStore *objectStore = ((MyAppDelegate*)[[UIApplication sharedApplication] delegate]).objectStore;

    id updateObject = (NSManagedObject*)[objectStore findOrCreateInstanceOfEntity:[resource entity] withPrimaryKeyAttribute:@"myID" andValue:[dictionary objectForKey:@"id"]];

    [updateObject setMyID:[dictionary objectForKey:@"id"]];

    // if marked for deletion, delete it now
    if ([[dictionary objectForKey:@"deleted_at"] isKindOfClass:[NSString class]]) {
        if ([updateObject isNew]){
            NSError *error = nil;
            [objectStore.managedObjectContext save:&error];
            if (error) {
                NSLog(@"error saving before delete: %@",error);
                return;
            }
//          [objectStore.managedObjectContext deleteObject:updateObject];
//          [objectStore.managedObjectCache delete:updateObject];  
        }
        else {
            [objectStore.managedObjectContext deleteObject:updateObject];            
        }
        return;
    }

    [updateObject updateWith:dictionary];
}

要注意的部分是带有(1)保存部分的deleted_at部分,(2)从上下文中删除对象,以及(3)从缓存中删除对象。我已经尝试了这三种组合,但我没有得到预期的结果。

如果我从缓存中删除它(只是#3):

  • 对象被保存但没有属性。

如果我从托管上下文中删除它(只是#2),我得到:

NSUnderlyingException=Cannot update object that was never inserted.

由于它从未插入,我以为我会保存它然后删除它(#1和#2),但后来我得到了:

*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xed27810 <x-coredata://4EE6AD5A-CC34-460A-A97A-0909454126A4/User/p166>''

那么从NSMangedObjectContext中删除“新”对象的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

使用RKManagedObjectStore获取[[RKObjectManager sharedManager] objectStore]实例更容易(假设您需要共享的实例,因为您在调用应用代理时似乎就这样做了。)

在创建NSManagedObject之前检查deleted_at密钥。此代码假定您要转换为Resource类型,NSManagedObject- (void)updateOrCreateObjectWith:(NSDictionary*)dictionary { RKManagedObjectStore *objectStore = [[RKObjectManager sharedManager] objectStore]; //get a reference to the object Resource *resource = [Resource findFirstByAttribute:@"myID" withValue:[dictionary objectForKey:@"id"]]; //see if "deleted_at" exists in dictionary if ([[dictionary objectForKey:@"deleted_at"] isKindOfClass:[NSString class]]) { //check to see if object exists in the context if(resource) { //if it exists, delete it [objectStore.managedObjectContext deleteObject:resource]; } } else { //no "deleted at", so create the object if (!resource) { //resource is nil (it doesn't exist in the context), so we need to create it resource = [Resource object]; } [resource updateWith:dictionary]; } NSError *error = nil; [objectStore.managedObjectContext save:&error]; if (error) { NSLog(@"error saving before delete: %@",error); } } 的子类。这是未经测试的,但应该让你知道你应该做什么。

{{1}}

答案 1 :(得分:1)

除非必要,否则您希望避免创建托管对象。最好的策略是遵循这个伪代码:

NSManagedObject *existingObject = ...; // fetch the object
if (existingObject) {
    if (deleted) {
        [self.managedObjectContext deleteObject: existingObject];
    }
} else {
    if (!deleted) {
        // create the object, insert it into the MOC, set the object properties
    }
}