代码:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"A"
inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"somePredicate", someObject];
[fetchRequest setPredicate:predicate];
frc = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:moc
sectionNameKeyPath:@"recency"
cacheName:@"frc"];
[fetchRequest release];
frc.delegate = self;
NSError *error;
BOOL success = [frc performFetch:&error];
if (!success) {
NSLog(@"error: %@", error);
}
for (A *a in [frc fetchedObjects]) {
[someMutableArray addObject:a.b];
[someMutableArray addObject:a];
}
数据模型:
A 和 B 是实体。A 与 B 具有强制的一对一关系。 B 与 A 具有逆可选的对多关系。
以上为英文:
初始化 NSFetchedResultsController 以获取一些数据来为 tableview 供电。初始提取后,将数据放在一边进行一些处理。
现在,稍后,我尝试这样做:
id object = [someMutableArray objectAtIndex:someIndex];
NSLog(@"%@", object);
if ([object isMemberOfClass:[B class]]) {
someVar = object.propertyFromB; // problem
} else if ([object isMemberOfClass:[A class]]) {
someVar = object.propertyFromA;
}
问题/问题:标有“问题”的行崩溃。(编辑:请参阅下面的解决方案,但仍需要解释。)
上面的 NSLog 调用产生:
2010-01-30 14:47:14.433 app[22618:20b] <B: 0xf7f750> (entity: B; id: 0xf7ba70 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/B/p4> ; data: <fault>)
2010-01-30 14:47:14.438 app[22618:20b] <A: 0xf7e360> (entity: A; id: 0xf35820 <x-coredata://B01FEC86-14D6-4973-BFDB-EDE4AFD24FDC/A/p6> ; data: {
prop1 = value1;
prop2 = value2;
... etc ...
})
即,通过有问题的行,如果对象是 A 类型,则它已出现故障并且在内存中可用,但如果它是 B,则它是故障。
我的理解是“问题”行应该触发故障并从存储中获取数据,但这并没有发生。我想了解/调试原因。我已经尝试围绕这个插入 willAccessKey/didAccessKey 调用。我还尝试在获取请求上设置 setRelationshipKeyPathsForPrefetching:"b" 。都没有奏效。
我的假设是,由于我在某种程度上滥用了 NSFetchedRequestController 结果,因此故障引擎在此过程中会感到困惑,并且不会在应有的时候获取故障。所以我想一个蛮力的方法是创建一个新的手动获取请求以在正确的时间获取相关的 B 对象。但是有更好的方法吗?
编辑:
问题是对象 B 有一个我定义的属性“描述”,但这与 NSObject 的内置名称冲突。Xcode 总是给我警告,但我忽略了它们,因为我认为“描述”内部属性/方法仅用于将字符串转储到控制台等,而不是内部处理。
在我制作了新版本的模型并将“描述”重命名为其他内容后,问题就消失了。所有的故障都开始按预期工作。
不过,我不明白发生了什么。Core Data 是否使用对象的“描述”方法进行一些内部自省?