当我第一次填充视图时,我这样做:
self.cats = [[DataManager sharedManager] getCatsFromCoreData]; //cats is an NSArray property (strong)
for (Cat* cat in self.cats)
{
CatThumbnailView *thumb = [CatThumbnailView catThumbnailView];
thumb.cat = cat;
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(thumbnailTapped:)];
[thumb addGestureRecognizer:tap];
[thumb setText:[cat.name uppercaseString]];
...
[self.someScrollview addSubview:thumb];
yPos += thumb.frame.size.height + spacing;
}
DataManager的get方法如下所示:
- (NSArray*)getCatsFromCoreData
{
NSManagedObjectContext *context = [[CoreDataController sharedController] managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Cats" inManagedObjectContext:context]];
[request setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"order" ascending:YES]]];
NSError *error = nil;
NSArray *fetchedCats = [context executeFetchRequest:request error:&error];
if (fetchedCats.count > 0) {
return fetchedCats;
}
return nil;
}
一切正常。视图已填充。缩略图点按方法如下所示:
- (void)thumbnailTapped:(UITapGestureRecognizer*)tap
{
CatThumbnailView* thumb = (CatThumbnailView*)tap.view;
DLog(@"cat %@", thumb.cat);
DLog(@"cat id: %@", thumb.cat.cat_id);
//do stuff here with the cat data
}
问题在于,有时当我点击猫缩图时,我得到了这个:
cat <Cat: 0x7fa450> (entity: Cat; id: 0x7b71f0 <x-coredata://7C904BD2-16AA-486D-8D1B-C2D0ABCCB6D4/Cat/p1> ; data: <fault>)
cat id: (null)
因为cat id为null,所以当我尝试使用它时,应用程序崩溃。
因此,当我第一次从CoreData检索cat对象并布局视图时,cat id永远不会为null。当我稍后点击其中一个缩略图时,数据已成为故障,因此当我访问cat_id属性时,它为null。 CatThumbnailView保留Cat实体:
@property (nonatomic, strong) Cat* cat;
为什么会发生这种情况,我该怎么办呢?
*注意 - 每次点击缩略图时都不会发生这种情况。我会说它发生在10-20%的时间。另外80-90%的时间数据不是故障。为什么????
答案 0 :(得分:5)
我知道这有点旧,但最可能的解释是你的Cat类的实现看起来像这样:
@implementation Cat
@synthesise cat_id = _cat_id;
...
@end
什么时候看起来像这样:
@implementation Cat
@dynamic cat_id;
...
@end
我自己也犯了这个错误,所以分享这个,希望它可以节省下一个人一点时间!
答案 1 :(得分:2)
在需要访问该对象的实际值之前,核心数据不会返回完整对象。在此之前,每个返回的对象都将是“错误”。
您可以[request setReturnsObjectsAsFaults:NO]
使用Fetch Request
来强制获取完整的对象,但在大多数情况下都不需要。
在你的情况下,我怀疑manageObjectContext
是一些如何达到无效状态或在获取对象时不可用。
而不是将
manageObjectContext
的范围限制在您的方法中 仅getCatsFromCoreData
,声明manageObjectContext
控制器级别,以便在实际时可用 取物。
<强> P.S。确保在实际获取对象时manageObjectContext
可用。
希望这会对你有所帮助。