Restkit和僵局

时间:2012-03-22 08:25:10

标签: ios5 deadlock restkit

目前我正在使用Restkit来控制我应用中的所有(Core-)数据。我正在使用它与使用RKManagedObjectMapping的服务器保持同步,我使用[myMyNSManagedObject createEntitity]和[[RKObjectManager§sharedManager] .objectStore save]来手动编辑Grand Central Dispatch中的项目。

是否有任何建议以此方式或其他方式执行此操作?因为有时应用程序会在执行此Restkit代码的死锁中冻结

+ (NSArray*)objectsWithFetchRequest:(NSFetchRequest*)fetchRequest {
    NSError* error = nil;
    NSArray* objects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    if (objects == nil) {
        RKLogError(@"Error: %@", [error localizedDescription]);
    }
    return objects;
}

- (NSError*)save {
    NSManagedObjectContext* moc = [self managedObjectContext];
    NSError *error;
    @try {
        if (![moc save:&error]) {
            if (self.delegate != nil && [self.delegate respondsToSelector:@selector(managedObjectStore:didFailToSaveContext:error:exception:)]) {
…

并行。在我切换到Restkit之前,我在每个实体编辑代码周围放置了一个“context performBlockAndWait”,并且在安全方面没有死锁。我没有其他NSManagedObjectContext或者我自己创建的东西,都来自Restkit。

2 个答案:

答案 0 :(得分:0)

就我而言,问题在于我是跨越线程边界传递NSManagedObjects,并在除了从各自的NSManagedObjectContext获取它们之外的线程上使用它们。在我的情况下,这真的很微妙,因为我知道我不应该这样做,但无论如何都不小心做了。我没有传递托管对象,而是开始传递NSManagedObjectIDs(然后从本地线程的MOC获取),并且从那时起就没有遇到过死锁。我建议您对代码进行深度扫描,以确保您只在生成它们的线程中使用托管对象。

答案 1 :(得分:0)

我们在应用中遇到了这个完全问题。基本上,CoreData嵌套上下文在iOS5中非常错误,因此不像宣传的那样工作。这有许多表现形式,但其中一个是上述问题,使获取请求与后台操作死锁。这是well documented,有启发性的引用:

  

NSFetchedResultsController死锁

     

您永远不希望您的应用程序陷入僵局。使用NSFetchedResultsController和嵌套上下文,这很容易做到。使用上述相同的UIManagedDocument设置,在将NSFetchedResultsController与主队列上下文一起使用时,在私有队列上下文中执行获取请求可能会死锁。如果你几乎在同一时间开始,几乎100%的一致性。 NSFetchedResultsController可能正在获取它不应该的锁。据报道,即将发布的iOS版本已经修复了这个问题。

This SO answer有一个可能的修复方法,可以保留嵌套的上下文。我见过其他人喜欢它,基本上可以自由地应用-performAndWait:个电话。我们还没有尝试过(iOS5在我们的用户群中有一位数的百分比)。否则,我们现在知道的唯一其他“修复”就是放弃iOS5的嵌套上下文(参见this SO answer)。

对于多线程(在iOS 5中),CoreData继续从根本上被打破,这在Apple方面是不可原谅的。现在,在CoreData(多线程,iCloud)上信任Apple似乎正在打开一大堆痛苦,你可以成为一个好的案例。