我在我的应用方案中激活了核心数据调试器-com.apple.CoreData.SQLDebug 1,对于名为Category的实体和名为Image的关系实体,得到了以下结果:

在主上下文上的FetchRequest:

NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"Category"];
fr.relationshipKeyPathsForPrefetching = @[@"image"];

NSArray *results = [self.mainContext executeFetchRequest:fr error:nil];

for (Category *category in results) {

    NSLog(@"%@", category.image.width);
}

控制台日志显示未实现任何错误-由于已将图像关系设置为预取,因此是预期的行为。

对子上下文的相同请求:
NSManagedObjectContext *privateMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[privateMOC setParentContext:self.mainContext];

[privateMOC performBlock:^{

        NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:@"Category"];
        fr.relationshipKeyPathsForPrefetching = @[@"image"];

        NSArray *results = [privateMOC executeFetchRequest:fr error:nil];

        for (Category *category in results) {

            NSLog(@"%@",category.image.width);
        }
    }];

在这种情况下,控制台将显示每个图像(其中四个)的核心数据实现故障。这是错误,预期的行为还是我想念一些东西?

最佳答案

实验:

我已经在测试应用程序中复制了您的方案,并得出了相同的结论:预取未在后台线程中进行。日志:

******************************** FOREGROUND **************************************

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZTIMESTAMP, t0.ZTITLE, t0.ZIMAGE FROM ZCATEGORY t0
CoreData: annotation: sql connection fetch time: 0.0004s
CoreData: annotation: Bound intarray values.
CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZURL FROM ZIMAGE t0 WHERE  t0.Z_PK IN (SELECT * FROM _Z_intarray0)
CoreData: annotation: sql connection fetch time: 0.0006s
CoreData: annotation: total fetch execution time: 0.0010s for 4 rows.
CoreData: annotation: Prefetching with key 'image'.  Got 4 rows.
CoreData: annotation: total fetch execution time: 0.0035s for 4 rows.

******************************** BACKGROUND **************************************

CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZTIMESTAMP, t0.ZTITLE, t0.ZIMAGE FROM ZCATEGORY t0
CoreData: annotation: sql connection fetch time: 0.0003s
CoreData: annotation: total fetch execution time: 0.0005s for 4 rows.

分析:

根据NSFetchRequestdocumentation,说明了提供预取以解决特定的性能挑战。描述如下(我的重点):



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

如果您已经在使用后台线程,则这种性能调整的重要性肯定会降低,并且通常的故障机制可以充分处理必要的优化。因此,属性relationshipKeyPathsForPrefetching将恢复为其默认值,即一个空数组。

关于ios - 核心数据子上下文未预取关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34018021/

10-13 08:59