如果我尝试在Core Data中预取相关实体,我就会遇到KVO异常问题。它对我没有任何意义,我似乎无法复制简化项目中的行为。我定位10.8并使用ARC。
我的数据为音乐库建模,我有三个感兴趣的实体:Track
,Artist
和Album
。一个曲目有一个艺术家和一个专辑,而一个专辑有一个艺术家。我的Album
和Artist
个对象是名称唯一的(只有一个艺术家在商店中有一个给定名称)。
我想显示包含以下字段的曲目列表:title,artist.name,album.title。使用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" 从中,很可能是因为键的值 "艺术家"在没有适当的KVO通知的情况下发生了变化 发送。检查Track类的KVO合规性。
在自定义NSArrayController
子类之前,一切正常。只需在我的setRelationshipKeyPathsForPrefetching
子类中注释掉NSArrayController
行,一切都可以正常工作。我无法确定预取和KVO之间的链接。有没有核心数据专家以前见过这样的东西?
答案 0 :(得分:1)
我遇到了同样的问题,这就是我在解决问题时学到的:
似乎NSArrayController在所有情况下都不能很好地与setRelationshipKeyPathsForPrefetching:
一起使用。我正在子上下文中执行预取请求,这最终破坏了父上下文中NSArrayController
的KVC,我认为这是非预期的行为。在任何情况下,我修复它的方式是使用"old" style (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:
覆盖中使用此方法,因为您需要先获取结果执行批处理错误请求。另外,你已经尝试过懒惰的抓取标志?