首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MagicalRecord ==Total背景?

MagicalRecord ==Total背景?
EN

Stack Overflow用户
提问于 2014-01-16 19:28:59
回答 1查看 149关注 0票数 0

在magicalRecord on iOS 7应用程序中,有两个NSManagedObjectContexts:

  1. RootSavingContext,NSPrivateQueueConcurrencyType型
  2. DefaultContext,NSMainQueueConcurrencyType型

在执行非常重的数据库时,.sqlite插入/更新/删除如何利用上述两种上下文,从而使数据库保存最终磁盘I/O也发生在后台,而不使用主线程。现在,MagicalRecord中的代码

代码语言:javascript
复制
+ (void)rootContextChanged:(NSNotification *)notification {
if ([NSThread isMainThread] == NO) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self rootContextChanged:notification];
    });

    return;
}

[[self MR_defaultContext] mergeChangesFromContextDidSaveNotification:notification];

}

使用主线程将数据保存到数据库。相反,整件事不可能发生在没有主线程干预的背景下。虽然MagicalRecord公开了用于创建后台NSManagedObjectContext的方法(如MR_Context ),但是在主线程上执行保存操作。我在GCD中创建背景上下文,然后像这样使用performBlockAndWait:

代码语言:javascript
复制
if ([bContext hasChanges]) {
            NSError* __autoreleasing error;
            [bContext save:&error];
            [bContext.parentContext saveToPersistentStoreAndWait];
        }
EN

回答 1

Stack Overflow用户

发布于 2014-01-16 19:39:18

我不能用魔法唱片说话,因为我从未用过它。

但是关于可能性,假设您使用了SQLite存储,有一个小问题: SQLite不允许同时进行多线程访问。根据它的开发人员“线是邪恶的,要避开它们。”

在核心数据术语中,这通常意味着从背景上下文实例化保存,SQL插入、删除等都发生在后台,写磁盘发生在后台等等,但当这种情况发生时,对持久存储的所有访问都被锁定。如果主队列试图运行查询,甚至只是对象中的错误,那么它必须阻塞,等待保存完成。

因此,至少在一个非常真实的意义上,您不能保证主线程不会受到任何影响,除非您能够保证主线程不会试图访问存储。

常见的解决方案包括在主队列上使用带有显式SQL样式获取的托管对象的字典版本,而不一定在主队列上使用,因为不可变的字典是线程安全的,使用由Core数据构建的其他自定义结构,但随后不太可能引用它,只是不担心后台保存相对较短,而且不太可能单击,或者甚至将后台的保存分割成小块,以减少主队列可能阻塞的最大时间。但是,对于最后一个对象要小心,因为插入成本在SQLite中是非线性的,因此,例如插入五个十个对象比插入五十个对象花费的时间更长。

我还设法从抓取任何我认为用户可能希望在不久的将来在主线程,当后台宣布,它计划很快保存一些良好的里程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21171073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档