1

再現不可能なクラッシュが発生しましたが、その理由がわかりません。バックグラウンド キューに画像をキャッシュしています。イメージ名は、Core Data NSManagedObject サブクラスである CCCard のプロパティです。同時に、これらの CCCard にもアクセスしているコレクション ビューがあります。

関連するコードと注意事項は次のとおりです。

//CCDeckViewController.m --------------------------------------

- (void)viewDidLoad {
    // This will fetch the CCCard objects from Core Data.
    self.cards = [[CCDataManager shared] cards];

    [self cacheImages];
}

- (void)cacheCardImages {
    // Because these are NSManagedObjects, I access them in the background
    // via their object ID. So pull the IDs out here.
    NSArray *cardIds = [self.cards valueForKey:@"objectID"];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        for (NSManagedObjectID *cardId in cardIds) {

            // Fetch the actual CCCard object.
            CCCard *card = (CCCard *)[[CCDataManager shared] objectWithId:cardId];

            // Cache the card's image if it's not already there.
            NSString *key = [card thumbnailCacheKey];
            if ([self.cardImageCache objectForKey:key]) {
                continue;
            }
            CCDiscardableImage *discardable = [CCHelper decompressedImageForPath:key size:[card thumbnailSize] tintable:[card tintable]];
            [self.cardImageCache setObject:discardable forKey:key];
        }
    });
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    CCCard *card = self.cards[indexPath.item];

    // This line calls the code that crashes.
    UIColor *color = [card color];

    // More code that returns the cell.
}


// CCCard.m --------------------------------------

- (UIColor *)color {
    // Crash happens on this line.
    if (self.colorId.integerValue == 0) {
        // some code
    }
}

Crashlytics レポートのスタック トレースのうち、最も関連性が高いと思われる部分を以下に示します。

Thread #0: Crashed: com.apple.main-thread
EXC_BREAKPOINT 0x000000000000defe
0  CoreData                       0x24c1b070 _sharedIMPL_pvfk_core + 247
1  CoreData                       0x24c1b071 _sharedIMPL_pvfk_core + 248
2  myapp                          0x4286f -[CCCard color] (CCCard.m:37)
3  myapp                          0x40bbb -[CCDeckViewController collectionView:cellForItemAtIndexPath:] (CCDeckViewController.m:127)

Thread #4: com.apple.root.utility-qos
0  libsystem_pthread.dylib        0x2321920c RWLOCK_GETSEQ_ADDR
1  libsystem_pthread.dylib        0x23219295 pthread_rwlock_unlock + 60
2  libobjc.A.dylib                0x22cb8e01 rwlock_tt<false>::unlockRead() + 8
3  libobjc.A.dylib                0x22cb5af5 lookUpImpOrForward + 488
4  libobjc.A.dylib                0x22cb5903 _class_lookupMethodAndLoadCache3 + 34
5  libobjc.A.dylib                0x22cbbd7b _objc_msgSend_uncached + 26
6  CoreData                       0x24c1d3ab _PFObjectIDFastEquals64 + 38
7  CoreFoundation                 0x233eeed4 CFBasicHashFindBucket + 1820
8  CoreFoundation                 0x233ee775 CFDictionaryGetValue + 116
9  CoreData                       0x24c17037 _PFCMT_GetValue + 122
10 CoreData                       0x24c16ec7 -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] + 58
11 CoreData                       0x24c1b45d _PF_FulfillDeferredFault + 940
12 CoreData                       0x24c1afcf _sharedIMPL_pvfk_core + 86
13 myapp                          0x42991 -[CCCard imagePath] (CCCard.m:53)
14 myapp                          0x41d5b __39-[CCDeckViewController cacheCardImages]_block_invoke (CCDeckViewController.m:295)

開発中には決して起こらないのでイライラするので、理論をテストすることはできません. コードとクラッシュ レポートを理解し、問題を解決しようとしています。私の推測では、CCCard オブジェクトのインスタンス メソッドにアクセスし、そこからプロパティを読み取ろうとするとクラッシュするため、フォルトと関係があると思われます。しかし、なぜ?

4

1 に答える 1

5

スレッドの制限に違反しています。

Core Data のドキュメントによると、aNSManagedObjectContextおよびそれNSManagedObjectに関連付けられているものは、割り当てられているキューでのみアクセスする必要があります。

あなたdispatch_asyncはその規則に違反しており、修正する必要があります。そういう中でCore Dataを使える設計はもうありませんdispatch_async

処理を非同期にしたい場合NSManagedObjectContextは、メインの子であるプライベートを生成し、NSManagedObjectContextそれに対して a を実行する必要があります-performBlock:。これにより、適切に構成されたバックグラウンド処理が提供されます。

-com.apple.CoreData.ConcurrencyDebug 1また、開発中にこのような問題が発生する可能性があるため、オンにすることを強くお勧めします。

于 2016-04-07T15:46:27.063 に答える