ios – 核心数据子上下文不预取关系

前端之家收集整理的这篇文章主要介绍了ios – 核心数据子上下文不预取关系前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在我的应用程序方案中激活了Core Data调试器-com.apple.CoreData.sqlDebug 1,并获得了一个名为Category的实体的以下结果,其中包含一个名为 Image的关系实体:

主要上下文中的FetchRequest:

  1. NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"Category"];
  2. fr.relationshipKeyPathsForPrefetching = @[@"image"];
  3.  
  4. NSArray *results = [self.mainContext executeFetchRequest:fr error:nil];
  5.  
  6. for (Category *category in results) {
  7.  
  8. NSLog(@"%@",category.image.width);
  9. }

控制台日志显示未完成任何故障 – 自映像关系设置为预取以来的预期行为.

对子上下文的相同请求:

  1. NSManagedObjectContext *privateMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
  2. [privateMOC setParentContext:self.mainContext];
  3.  
  4. [privateMOC performBlock:^{
  5.  
  6. NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"Category"];
  7. fr.relationshipKeyPathsForPrefetching = @[@"image"];
  8.  
  9. NSArray *results = [privateMOC executeFetchRequest:fr error:nil];
  10.  
  11. for (Category *category in results) {
  12.  
  13. NSLog(@"%@",category.image.width);
  14. }
  15. }];

在这种情况下,控制台显示Core Data为每个图像(其中4个)执行故障.这是一个错误,预期的行为还是我错过了什么?

解决方法

实验:

我已经在测试应用程序中复制了您的场景并得出了相同的结论:预取不会在后台线程中发生.日志:

  1. ******************************** FOREGROUND **************************************
  2.  
  3. CoreData: sql: SELECT 0,t0.Z_PK,t0.Z_OPT,t0.ZTIMESTAMP,t0.ZTITLE,t0.ZIMAGE FROM ZCATEGORY t0
  4. CoreData: annotation: sql connection fetch time: 0.0004s
  5. CoreData: annotation: Bound intarray values.
  6. CoreData: sql: SELECT 0,t0.ZNAME,t0.ZURL FROM ZIMAGE t0 WHERE t0.Z_PK IN (SELECT * FROM _Z_intarray0)
  7. CoreData: annotation: sql connection fetch time: 0.0006s
  8. CoreData: annotation: total fetch execution time: 0.0010s for 4 rows.
  9. CoreData: annotation: Prefetching with key 'image'. Got 4 rows.
  10. CoreData: annotation: total fetch execution time: 0.0035s for 4 rows.
  11.  
  12. ******************************** BACKGROUND **************************************
  13.  
  14. CoreData: sql: SELECT 0,t0.ZIMAGE FROM ZCATEGORY t0
  15. CoreData: annotation: sql connection fetch time: 0.0003s
  16. CoreData: annotation: total fetch execution time: 0.0005s for 4 rows.

分析:

根据NSFetchRequest的documentation,解释了提供预取以解决特定的性能挑战.它描述如下(我的重点):

Prefetching allows Core Data to obtain related objects in a single fetch (per entity),rather than incurring subsequent access to the store for each individual record as their faults are tripped. For example,given an Employee entity with a relationship to a Department entity,if you fetch all the employees then for each print out their name and the name of the department to which they belong,it may be that a fault has to be fired for each individual Department object (for more details,see Core Data Performance in Core Data Programming Guide). This can represent a significant overhead. You could avoid this by prefetching the department relationship in the Employee fetch…

从其措辞可以看出,这不是提高性能的必要设备.这可以解释为什么它没有在后台线程上实现:讨论中描述的性能问题似乎表明涉及UI更新的典型场景.在我看来,这澄清了这个功能的意图.

如果您已经在后台线程中,那么这种性能调优肯定不那么重要,并且通常的故障机制可以充分地处理必要的优化.因此属性relationshipKeyPathsForPrefetching将恢复为其默认值,即空数组.

猜你在找的iOS相关文章