iOS - 导致空值的CoreData错误

sol*_*eil 6 core-data fault uiview ios

当我第一次填充视图时,我这样做:

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;
    }
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

一切正常.视图已填充.缩略图点按方法如下所示:

- (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

}
Run Code Online (Sandbox Code Playgroud)

问题是,有时当我点击猫缩图时,我得到这个:

cat <Cat: 0x7fa450> (entity: Cat; id: 0x7b71f0 <x-coredata://7C904BD2-16AA-486D-8D1B-C2D0ABCCB6D4/Cat/p1> ; data: <fault>)
cat id: (null)
Run Code Online (Sandbox Code Playgroud)

因为cat id为null,所以当我尝试使用它时,应用程序会崩溃.

因此,当我第一次从CoreData检索cat对象并布局视图时,cat id永远不会为null.当我稍后点击其中一个缩略图时,数据已成为故障,因此当我访问cat_id属性时,它为null.CatThumbnailView保留了Cat实体:

@property (nonatomic, strong) Cat* cat;
Run Code Online (Sandbox Code Playgroud)

为什么会发生这种情况,我该怎么办呢?

*注意 - 每次点击缩略图时都不会发生这种情况.我会说它发生在10-20%的时间.另外80-90%的时间数据不是故障.为什么????

sme*_*mee 5

我知道这有点旧,但最可能的解释是你的Cat类的实现看起来像这样:

@implementation Cat
@synthesise cat_id = _cat_id;
...
@end
Run Code Online (Sandbox Code Playgroud)

什么时候看起来像这样:

@implementation Cat
@dynamic cat_id;
...
@end
Run Code Online (Sandbox Code Playgroud)

我自己也犯了这个错误,所以分享这个,希望它可以节省下一个人一点时间!


Moi*_*med 2

在需要访问该对象的实际值之前,核心数据不会返回完整的对象。在此之前,您返回的每个对象都将是“错误”。

你可以使用[request setReturnsObjectsAsFaults:NO]onFetch Request来强制获取完整的对象,但这在大多数情况下是不必要的


就您而言,我怀疑manageObjectContext是如何达到无效状态或在获取对象时不可用的。

不要将 的manageObjectContext范围仅限于您的方法 getCatsFromCoreData,而是manageObjectContext在控制器级别进行声明,以便它在实际获取对象时可用。

PS 确保manageObjectContext在实际获取对象时可用。

希望对你有帮助。