同时写入和读取核心数据会导致 UI 冻结,直到写入完成



当我的应用程序启动时,它会将一组实体与服务器同步。在此同步期间,它会更新核心数据中的实体并保存它。如果您打开应用程序(同步开始),然后我按下我的标签栏按钮,该按钮应该显示tableView(使用NSFetchedResultsController),它会冻结片刻。

我真的不知道在哪里寻找这个问题。

使用一些额外信息进行更新:

我正在使用用于获取 NSFetchedResultsController 的主(父)上下文和同步类中使用的 chil 上下文来下载和保存更改。

完成所有更改后,我依次保存子上下文和父(主)上下文。(我认为这是必要的。

我从您的陈述中假设您的主上下文是这样创建的

let mainContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
    mainContext.persistentStoreCoordinator = CoreDatStack.sharedStack.persistentStoreCoordinator

您已创建如下子上下文

let childContext = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType)
    childContext.parent = mainContext

冻结原因:主上下文的保存操作在主线程上执行(因为写入磁盘(持久存储)的过程很慢),因此阻塞主线程直到保存操作完成。

解决方案:在 privateQueue 上建立与 PersistentStoreCoordinator 链接的上下文,以便保存不会在主队列上执行。

在viewDidLoad中添加如下内容:

dispatch_queue_t jsonParsingQueue = dispatch_queue_create("jsonParsingQueue", NULL);
// execute a task on that queue asynchronously
dispatch_async(jsonParsingQueue, ^{
    //fetch code here

    // some code on a main thread (delegates, notifications, UI updates...)
    dispatch_async(dispatch_get_main_queue(), ^{
     //UI updates here

    });
});

最新更新