使用 Restkit 在 Core Data 中删除后保存对象使其崩溃

Posted

技术标签:

【中文标题】使用 Restkit 在 Core Data 中删除后保存对象使其崩溃【英文标题】:Save an object after Delete in Core Data with Restkit make it crash 【发布时间】:2012-01-30 12:53:47 【问题描述】:

我正在尝试使用 RestKit 和 Core Data 作为服务器端数据的本地缓存,但我无法做到

我创建了一个 NSManagedObject :

@interface JSONShop : NSManagedObject

@property (nonatomic, retain) NSNumber * shopId;
@property (nonatomic, retain) NSNumber * type;

@end
@implementation JSONShop

@synthesize shopId;
@synthesize type ;

@end

它由 Restkit 自动映射和存储,我可以从数据库中获取它以显示在 TableViewController 中。

我的表上有一个主键(在我的映射中定义),例如:

shopMap.primaryKeyAttribute = @"shopId" ;  

当我第一次存储我的对象时,一切都很好:)

之后,当我删除上下文中的所有实体时,当 Restkit 尝试再次映射它并再次保存它但我收到此错误:

'CoreData could not fulfill a fault for '0x9412ea0 <x-coredata://F8451322-3890-430F-8ABD-B5EEF1DFED2F/JSONShop/p177>'' 

你知道为什么吗?

这是我的删除代码:

- (void) deleteAllObjects: (NSString *) entityDescription  

    NSLog(@"Deleting %@",entityDescription);

    NSManagedObjectContext * managedObjectContext = [[RKObjectManager sharedManager].objectStore managedObjectContext] ;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:managedObjectContext];
    NSError * error ;
    [fetchRequest setEntity:entity];

    NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

    for (NSManagedObject *managedObject in items) 
        [managedObjectContext deleteObject:managedObject];
    
    if (![managedObjectContext save:&error]) 
        NSLog(@"Error deleting %@ - error:%@",entityDescription,error);
    


【问题讨论】:

删除和下载/保存是否发生在同一个线程中,并在删除后保存顺序? 我想是的,在 MainThread 上按以下顺序完成操作 1. 使用将数据存储在 Core Data 中的 Restkit 获取 2. 手动删除数据 3. 使用 Restkit 再次获取 => 崩溃 您在所有这些中使用相同的 managedObjectContext 吗? 是的,我正在使用这个:[[RKObjectManager sharedManager].objectStore managedObjectContext]。 对不起,我无法完全解决这个问题。在一个线程上使用标准 managedobjectcontext 描述的模式应该会成功。 【参考方案1】:

因此,您正在使用 Restkit 获取数据,并使用 RestKit 将数据存储在 CoreData Moc 中。

我没有看到您实际将更改保存到磁盘的位置。

为什么不使用 RestKit 获取对象然后删除它们呢?即

- (IBAction)deleteAllButtonClicked:(id)sender 

    NSArray* objects = [JSONShop findAll]; 
    for (JSONShop *object in objects)  
        [[JSONShop managedObjectContext] deleteObject:object]; 
     
    NSError* error = nil; 
    [[JSONShop managedObjectContext] save:&error]; 
    if (nil != error)  
        // Error checking here... 
    

此示例项目类似:lottadot-restkit-ios-rails3-1-advanced

【讨论】:

感谢您的回答,这是我尝试过的解决方案之一,但以同样的方式失败...【参考方案2】:

在 RestKit 0.10 之前,RKManagedObjectStore 保存每个使用实体的缓存副本。但是当实体从 CoreData 中删除时,对象被保存在缓存中。因此,稍后当您想要重新保存同一个对象时,它不是在 CoreData 中创建它,而是从其缓存中获取(错误)对象。 我遇到了完全相同的问题,请参阅CoreData validation error 1550

两种解决方案:

升级到 RestKit 0.10(问题已作为商店的更大返工的一部分得到修复) 或修补您当前的 RKManagedObjectStore 以禁用内存缓存

【讨论】:

以上是关于使用 Restkit 在 Core Data 中删除后保存对象使其崩溃的主要内容,如果未能解决你的问题,请参考以下文章

使用 Restkit 在 Core Data 中删除后保存对象使其崩溃

与 Core Data 和 RestKit 无关的关系

RestKit / Core Data:远程删除的实体不会从 Core Data 中删除

Core Data 和 Restkit 简单轻量级迁移错误

RestKit 到 Core Data 的映射和加载零对象。 RKManagedObjectLoader

RestKit 0.20.1 将本地 JSON 映射到 Core Data 崩溃