6

ビューに最初にデータを入力するときは、次のようにします。

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)

猫の ID が null であるため、何かをしようとするとアプリがクラッシュします。

そのため、最初に CoreData から猫オブジェクトを取得してビューをレイアウトするときに、猫 ID が null になることはありません。後でサムネイルの 1 つをタップすると、データがエラーになり、cat_id プロパティにアクセスすると null になります。CatThumbnailView は Cat エンティティを保持します。

@property (nonatomic, strong) Cat* cat;

なぜこれが起こるのか、どうすればよいのでしょうか?

*注 - これは、サムネイルをタップするたびに発生するわけではありません。10~20%の確率で起こると言われています。残りの 80 ~ 90% の時間は、データに問題はありません。どうして????

4

2 に答える 2

5

これが少し古いことは知っていますが、最も可能性の高い説明は、 Cat クラスの実装が次のようになったことです。

@implementation Cat
@synthesise cat_id = _cat_id;
...
@end

次のようになります。

@implementation Cat
@dynamic cat_id;
...
@end

私は自分でこの間違いを犯したので、次の人が少し時間を節約できることを願ってこれを共有します!

于 2014-02-16T21:52:04.923 に答える
2

そのオブジェクトの実際の値にアクセスする必要があるまで、コア データは完全なオブジェクトを返しません。返された各オブジェクトは、この時点まで「障害」になります。

[request setReturnsObjectsAsFaults:NO]onを使用しFetch Requestて完全なオブジェクトを強制的に取得できますが、ほとんどの場合、これは必要ありません


manageObjectContextあなたの場合、オブジェクトのフェッチ時に無効な状態に達したか、利用できないと思われます。

manageObjectContextのスコープをメソッド のみに制限する代わりに、コントローラ レベルgetCatsFromCoreDataで宣言manageObjectContextして、オブジェクトの実際のフェッチ時に使用できるようにします。

PSmanageObjectContextは、オブジェクトの実際のフェッチ時に利用可能であることを確認してください。

これがあなたを助けることを願っています。

于 2013-11-01T14:02:09.217 に答える