Coredata magicrecord 在后台获取对象进入 <fault> 状态

Posted

技术标签:

【中文标题】Coredata magicrecord 在后台获取对象进入 <fault> 状态【英文标题】:Coredata magicalrecord fetching objects in background go in <fault> state 【发布时间】:2013-09-01 16:14:22 【问题描述】:

我正在使用 MagicalRecord 库加载一些用于填充 tableview 的 CoreData 对象。这是一个缓慢的操作,因此我试图在后台威胁上执行此操作。 这一切似乎都很顺利,数据被加载到self.products,只有在一段时间(+-分钟)之后,所有加载的对象似乎都进入&lt;fault&gt; 状态。我不明白为什么会这样,有人知道吗?

- (void)doInBackground

 dispatch_queue_t myQueue = dispatch_queue_create("com.mycompany.myqueue", 0);
    dispatch_async(myQueue, ^
        [self reloadData];

        dispatch_sync(dispatch_get_main_queue(), ^

            [MBProgressHUD hideHUDForView:self.view animated:YES];
            [self performSelectorOnMainThread: @selector(sortData:) withObject:self waitUntilDone:YES];

        );
    );


- (void)reloadData

 NSArray *allProducts = [NSArray array];    
 allProducts =   [NSArray arrayWithArray:[Product MR_findAll]];
 self.products = [NSArray arrayWithArray:allProducts];
 

【问题讨论】:

【参考方案1】:

首先,您通过仅使用 MR_findAll 而不指定上下文来隐式使用默认上下文。这最终会导致崩溃或其他未知行为。其次,您不需要所有这些 NSArray。 MR_findAll(和所有其他 MR_find* 方法)的返回值返回一个结果数组。无需将内容从一个数组移动到另一个数组...

最后,你的问题。因为您正在主上下文队列上进行提取,所以无论如何您的提取都会阻止 UI。您需要创建一个 Private Queue 上下文并使用它执行您的提取,如下所示:

NSManagedObjectContext *privateQueueContext = [NSManagedObjectContext MR_privateQueueContext];
NSArray *results = [Product MR_findAllInContext:privateQueueContext];

此外,您可能需要考虑批量获取。查看有关获取获取请求的文档,如下所示:

NSFetchRequest *request = [Product MR_requestAllInContext:privateQueueContext];
//update batch size here

MagicalRecord 在内部设置了批量大小,但如果您需要更改它,您可以这样做。

【讨论】:

很抱歉,这有点令人困惑,MagicalRecord 无法识别 MR_privateQueueContext。您能否将我的代码重写为可以解决获取的对象进入 状态的问题? MR_privateQueueContext 位于功能/实验分支上。在我整理将一些实验性功能带回开发/主干线的细节时,请先尝试切换到该版本。 @casademora 我遇到了同样的问题,即缓慢获取导致 UI 阻塞。 MR_privateQueueContext 没有已知的类方法。我知道您建议切换到实验分支,但我想知道是否有可靠的方法来处理这个问题?

以上是关于Coredata magicrecord 在后台获取对象进入 <fault> 状态的主要内容,如果未能解决你的问题,请参考以下文章

magicrecord 删除非导入数据

如何在magicrecord中指定合并策略

核心数据不持久:使用magicrecord

JRDB:iOS对FMDB的超好用封装

点击按钮时停止在后台保存到 coredata

在后台线程中加载 CoreData