我正在加载CoreData中的对象列表,如下所示:
- (NSMutableArray *)loadAllPoisFromCache:(BOOL)includeCustom {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"PointOfInterest" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:@"sortOrder" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
if(!includeCustom) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(custom == %i)",NO];
[request setPredicate:predicate];
}
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
[request release];
return mutableFetchResults;
}
“PointOfInterest”实体是COMPPointOfInterest,它与实体“Location”有一个关系,它是一个COMPLocationEntity。
然后我循环结果:
NSMutableArray *mutableFetchResults = [self loadAllPoisFromCache:YES];
if (mutableFetchResults != nil && [mutableFetchResults count] > 0) {
NSLog(@"NOTIF_PoisLoaded with data from cache");
for (COMPPointOfInterest *aPoi in mutableFetchResults) {
COMPLocationEntity *locBeforePrintingOutPoi = aPoi.locationEntity;
NSLog(@"Loc class before printing out parent POI = %@", [locBeforePrintingOutPoi class]);
NSLog(@"Loaded POI %@ from cache %@ and location %@", aPoi.poiId, [aPoi class], [locBeforePrintingOutPoi class]);
NSLog(@"Loaded POI from cache %@", aPoi);
COMPLocationEntity *locAfterPrintingOutPoi = aPoi.locationEntity;
NSLog(@"Loc class refetched from parent POI after printing out POI = %@", [locAfterPrintingOutPoi class]);
NSNumber *lat2 = locAfterPrintingOutPoi.latitude;
NSLog(@"Lat from refetched loc %@", lat2);
// crash on next line!
NSNumber *lat = locBeforePrintingOutPoi.latitude;
NSLog(@"Lat %@", lat);
}
现在,这就是我被困住的地方,如果你运行它,输出如下:
2011-01-24 16:35:41.063 NEC Companion [11959:207] NOTIF_PoisLoaded with cache from cache
2011-01-24 16:35:41.064 NEC Companion [11959:207]在打印出父POI之前的Loc类POI = _NSObjectID_48_1
2011-01-24 16:35:41.068 NEC Companion [11959:207]从缓存COMPPointOfInterest和位置_NSObjectID_48_1加载POI 1
2011-01-24 16:35:41.069 NEC Companion [11959:207]从缓存中加载POI(实体:PointOfInterest; id:0xae19110; data:{ cacheDate =“2011-01-24 16:09:26 +0000”; custom = 0; locationEntity =“0xae18ff0”; logoUrl =“http://192.168.37.213/companion/images/mapicons/es”; poiId = 1; sortOrder = 0; })
2011-01-24 16:35:41.071 NEC Companion [11959:207]在打印出POI = COMPLocationEntity之后从父POI重新获取Loc类
2011-01-24 16:35:41.072 NEC Companion [11959:207] Lat来自refetched loc 52.460118
2011-01-24 16:35:41.072 NEC Companion [11959:207] - [_ NSObjectID_48_1纬度]:无法识别的选择器发送到实例0xae18ff0
我的问题的症结在于,如果我在开始遍历列表时立即从POI中获取“locationEntity”属性,那么该类将作为_NSObjectID_48_1发出,然后我执行NSLog(@“从缓存中加载POI% @“,aPoi);然后我再次获得“locationEntity”属性,最终得到正确的COMPLocationEntity类!
所以看起来调用描述方法正在做一些事情来正确地完全实例化POI ......但是什么?
任何帮助都非常感激。
答案 0 :(得分:2)
是的,看起来我已经解决了。我的问题确实是locationEntity是一个关系,并在我的查询中添加以下内容会导致对象正确加载,我的位置关系已完全填充。
[request setRelationshipKeyPathsForPrefetching: [NSArray arrayWithObject:@“locationEntity”]];
答案 1 :(得分:1)
看起来它是错误的 - 在你特别要求它之前,CoreData没有得到数据。
您已指定在创建获取请求时不会在结果中对每个aPoi的属性进行错误处理。这意味着它具有COMPointOfInterest对象的所有属性。
然而,这并不意味着它的所有关系的对象都没有出现故障 - 您的COMPLocationEntity对象是(我假设)一种关系。 CoreData在特别要求之前不会获得这些,并且在此之前将它们标记为故障。因此获得一个非常奇怪的对象名称。当你问一个COMPLocationEntity的属性(在这种情况下,说明*),故障火灾和真实COMPLocationEntity对象加载。
这一行引发了错误:
NSLog(@"Loaded POI from cache %@", aPoi);
核心数据需要一些真实的数据输出你的APol对象,以便去,并从数据库中获取它,使COMPLocationEntity对象。
希望有所帮助。
*通常,在NSManagedObject 上调用描述不会导致错误(故意这样做)。您是否覆盖了类中的描述方法以输出更有用的内容?如果是这样,你就会自己触发故障!