3

如果我尝试在 Core Data 中预取相关实体,则会引发 KVO 异常。这对我来说没有任何意义,我似乎无法在简化项目中复制这种行为。我的目标是 10.8 并使用 ARC。

我的数据为音乐库建模,我有三个感兴趣的实体:TrackArtistAlbum。曲目有一个艺术家和一个专辑,而专辑有一个艺术家。我的AlbumArtist对象的名称是唯一的(商店中只有一位具有给定名称的艺术家)。

我想显示包含以下字段的曲目列表:标题、艺术家姓名、专辑标题。这很容易使用 NSArrayController 来实现Track实体和 NSTableView 中的绑定。

但是,由于我知道我将使用艺术家和专辑关系,所以我想在加载曲目时预取它们。我使用自定义 performFetch: 方法创建了一个 NSArrayController 子类,如下所示:

- (BOOL) fetchWithRequest:(NSFetchRequest *)fetchRequest merge:(BOOL)merge error:(NSError *__autoreleasing *)error
{
    NSEntityDescription *entityDescription = [Track entityInManagedObjectContext:[self managedObjectContext]];
    fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entityDescription];
    [fetchRequest setRelationshipKeyPathsForPrefetching:@[@"album", @"artist"]];

    return [super fetchWithRequest:fetchRequest merge:merge error:error];
}

我将 IB 中的 NSArrayController 的类设置为我的子类,并且我预计 UI 滞后会消失(每次滚动都会触发故障)。但是,抛出异常:

2013-01-01 10:48:06.965 XXX[10593:303] 无法为观察者更新关键路径“artist.name” from ,很可能是因为在没有适当的 KVO 通知的情况下,关键“艺术家”的值已更改发送。检查 Track 类的 KVO 合规性。

在自定义NSArrayController子类之前一切正常。通过简单地注释掉setRelationshipKeyPathsForPrefetching我的NSArrayController子类中的行,一切都会再次起作用。我无法确定预取和 KVO 之间的联系是什么。以前有没有 Core Data 专家见过这样的事情?

4

1 回答 1

1

我遇到了基本相同的问题,这是我在解决它时学到的:

似乎 NSArrayControllersetRelationshipKeyPathsForPrefetching:在所有情况下都不能很好地发挥作用。我在子上下文中执行预取请求,这最终破坏NSArrayController了父上下文中的 KVC,我认为这是意外行为。无论如何,我修复它的方法是使用“旧”样式(10.4) prefetching,它看起来像......

NSFetchRequest *trackReq = [[NSFetchRequest alloc] initWithEntityName:@"Track"];
NSArray *fetchedTracks = [context executeFetchRequest:trackReq error:&error];

NSFetchRequest *batchFaultReq = [[NSFetchRequest alloc] initWithEntityName:@"Artist"];
[batchFaultReq setPredicate:[NSPredicate predicateWithFormat:@"SELF.tracks in %@", fetchedTracks];
NSArray *faultedItems = [context executeFetchRequest:batchFaultReq error:&error];

// do something with fetchedTracks

...如何将其插入NSArrayController子类是另一回事-我不清楚如何在fetchWithRequest:覆盖中使用此方法,因为在执行批处理故障请求之前需要获取的结果。顺便说一句,您是否尝试过惰性获取标志?

于 2013-01-21T18:04:37.033 回答