核心数据冻结所有应用程序

Posted

技术标签:

【中文标题】核心数据冻结所有应用程序【英文标题】:Core Data freezing all the app 【发布时间】:2014-05-21 03:31:20 【问题描述】:

我在我的 ios 应用程序上遇到了 Core Data 并发问题。 在我的executeFetchRequest 上,我尝试同步managedObjectContext 请求,但有时这种方法会使我的应用程序冻结。

- (NSArray *)synchronizedWithFetchRequest:(NSFetchRequest *)request andError:(NSError **)error

    @synchronized(self.managedObjectContext)
    
        return [self.managedObjectContext executeFetchRequest:request error:error];
    

我已经尝试过很多方法,例如lock/unlockperformBlock/performBlockAndWaitdispatch_sync/dispatch_async,但似乎没有任何效果。

托管对象上下文创建:

 ...
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];

有没有办法解决这个问题?并让我的请求返回此方法上的结果对象?

谢谢!

【问题讨论】:

【参考方案1】:

在 MOC 上同步表明有多个线程访问同一个 MOC。 这本身就违反了 CoreData 并发协议。

禁止这种访问,除非它被包装在上下文performBlock: 方法(或其“等待”对应物)中。这将完全不需要 @synchronized 块。

此线程/队列“边界”扩展到获取/注册托管对象的上下文,因此,您将无法将它们作为方法的返回值进行访问。

【讨论】:

谢谢丹!那么处理多线程访问 Core Data 的最佳解决方案是什么?每个线程一个 MOC? 从阅读 THIS 开始。你可能会使用THIS 一般来说:每个线程/队列都有一个上下文绑定,在上下文之间传递对象是通过传递它们的objectIDs 并在另一个上下文中获取它们来完成的 我正在尝试实现嵌套上下文模式,但我不明白如何使用临时上下文。我应该为每次提取使用临时上下文吗?什么时候应该使用主上下文? 您使用临时上下文或每个后台操作,或作为后台操作,因为上下文选择其在队列上执行(使用performBlock:)。每个上下文都应该通过请求或 ID 获取它想要与之交互的对象。主上下文用作私有上下文的焦点,以合并更改并将其报告给 UI。不要忘记一直保存到商店以保留您的更改。

以上是关于核心数据冻结所有应用程序的主要内容,如果未能解决你的问题,请参考以下文章

核心数据:保存结束时冻结

TableView 由于核心数据错误而崩溃/冻结

使用 NSFetchedResultsController 从数据库中获取导致应用程序冻结

UI 冻结与神奇的记录

重新加载数据时iOS uitableview冻结

即使我在单独的线程中运行,QT GUI 也会冻结