Magical Record - 在主线程块 ui 中获取,在后台返回 nil

Posted

技术标签:

【中文标题】Magical Record - 在主线程块 ui 中获取,在后台返回 nil【英文标题】:Magical Record - fetch in main thread block ui, in background return nil 【发布时间】:2014-01-28 10:07:08 【问题描述】:

我是 Magical Record 的新手,但已经看过一些关于 *** 的问题,但找不到我的问题的答案。

我必须使用这种类型的结构找到带有谓词的项目:

NSArray *result = [MOSomeItems MR_findAllWithPredicate:predicate];

在主线程结果返回一些值,但 UI 卡住了。

使用此构造时,结果返回 nil 值:

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^
NSArray *result = [MOSomeItems MR_findAllWithPredicate:predicate];
);

在后台获取数据的最佳做法是什么?

【问题讨论】:

【参考方案1】:

您需要使用带有私有队列的上下文,然后使用获取的 ID 从主上下文中提取结果。

// Create a child context of our main context
NSManagedObjectContext *privateContext = [NSManagedObjectContext MR_context];
// When using private contexts you must execute the core data code in it's private queue using performBlock: or performBlockAndWait:
[privateContext performBlock:^
  // Execute your fetch
  NSArray *privateObjects = [MOSomeItems MR_findAllWithPredicate:predicate inContext:privateContext];
  // Convert your fetched objects into object IDs which can be pulled out of the main context
  NSArray *privateObjectIDs = [privateObjects valueForKey:@"objectID"];
  // Return to our main thread
  dispatch_async(dispatch_get_main_queue(), ^
    // Create a new predicate to use to pull our objects out
    NSPredicate *mainPredicate = [NSPredicate predicateWithFormat:@"self IN %@", privateObjectIDs];
    // Execute your fetch
    NSArray *finalResults = [MOSomeItems MR_findAllWithPredicate:mainPredicate];
    // Now you can use finalResults however you need from the main thread
  );
];

您还可以使用 -[NSManagedObjectContext objectWithID:] 方法提取对象,将 privateObjectIDs 数组中的每个对象作为参数传递,但这种方法更短。我还建议您考虑创建一个提取请求(MagicalRecord 有一个 MR_fetchAllWithPredicate: 方法),设置批量大小并手动执行提取。这将允许 Core Data 在返回数组的幕后以块的形式提取数据,以防止线程阻塞。

希望有帮助!

【讨论】:

谢谢詹姆斯理查德!我试过你的版本,它对我有帮助。你能说,我是对的吗,我设置了这样的批量大小:request.fetchLimit = 20;?谢谢! 很高兴它有帮助。 fetchLimit 属性将限制您的整个结果集,因此您只能返回 20 个对象。您想使用 result.fetchBatchSize 批处理所有对象。 :) @JamesRichard,感谢您的出色回答。我只是想知道,是否有任何处理错误。 不需要加__block吗? 您好,当我使用复合谓词时,您能帮忙吗?

以上是关于Magical Record - 在主线程块 ui 中获取,在后台返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

AFNetwork、Magical Record和块内保存

Magical Record 检测到默认上下文没有变化

更改的属性未与 Magical Record 一起保存

使用 Swift 3 在 Magical Record 中保存上下文时出错

Magical Record - 设置时崩溃

Magical Record 因此消息而崩溃