【问题标题】:How to delete new objects from NSManagedObjectContext如何从 NSManagedObjectContext 中删除新对象
【发布时间】:2012-04-03 04:41:08
【问题描述】:

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

- (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];
}

需要注意的部分是 deleted_at 部分,其中包含 (1) 保存部分,(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 中删除“新”对象的正确方法是什么?

【问题讨论】:

    标签: objective-c nsmanagedobject restkit nsmanagedobjectcontext


    【解决方案1】:

    使用[[RKObjectManager sharedManager] objectStore] 获取RKManagedObjectStore 实例更容易(假设您想要共享的实例,因为您正在调用您的应用委托,所以您似乎这样做了)。

    在创建 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);
        }
    }
    

    【讨论】:

    • 感谢您的回答。我想我一直在尝试将方形钉子放入圆孔中。我一直在使用单个 RKManagedObjectStore,因为我在下载后尝试在对象上建立关系时遇到了问题。它只是没有找到我知道的东西。有什么建议吗?
    • 共享的 RKManagedObjectStore 可能与委托的 objectStore 相同,除非您没有在 sharedManager 上设置 objectStore 属性。至于你的另一个问题,没有看到一些代码很难回答;您应该考虑在 google 群组或 irc 频道中发布另一个问题或提问。
    【解决方案2】:

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

    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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 2011-08-17
      • 2011-01-12
      • 1970-01-01
      相关资源
      最近更新 更多