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