1

時折起こるクラッシュレポートをユーザーから受け取りました(自分では再現できません)。それはNSManagedObjectContext refreshObjectと関係があります。クラッシュメッセージ「アンNSManagedObjectContextは、他のコンテキスト内のオブジェクトを更新することはできません」NSManagedObjectContextでクラッシュするrefreshObject

ある

それがクラッシュするコードはここにある:

dispatch_async(self.filterMainQueue, ^{ 
    NSArray *items = [Person getAllNonPrivatePersonsWithContext: self.backgroundContextImage]; 

    if (items.count) { 

     for (Person *person in items) { 

       [self.backgroundContextImage performBlockAndWait: ^{ 
        [person loadContactReferenceAndImage]; 

        // crashes here 
        [self.backgroundContextImage refreshObject: person mergeChanges:NO]; 
       }]; 
     }    
    } 
}); 

+ (NSArray *) getAllNonPrivatePersonsWithContext: (NSManagedObjectContext *) context{ 

    __block NSArray *items = nil; 

    [context performBlockAndWait: ^{ 
     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
     // Edit the entity name as appropriate. 
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext: context]; 
     [fetchRequest setEntity:entity]; 
     // Set the batch size to a suitable number. 
     //[fetchRequest setFetchBatchSize: 500]; 
     [fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"isContactPrivate == FALSE"]]; 
     [fetchRequest setReturnsObjectsAsFaults: FALSE]; 
     [fetchRequest setIncludesPendingChanges: FALSE]; 

     NSError *error = nil; 
     items = [context executeFetchRequest:fetchRequest error:&error]; 

    }]; 
    return items; 
} 

これは、なぜ私はかなりよく分かりませんクラッシュする。 backgroundContextImageNSPrivateQueueConcurrencyTypeを使用して作成されており、そのコンテキストで管理対象オブジェクトを取得してアクセスするときにはperformBlockAndWaitを使用していることを確認します。 filterMainQueueはシリアルキューで、メインスレッドではなくバックグラウンドスレッドでこの作業を行うのに役立ちます。

クラッシュレポートは次のようになります。

Exception Type: SIGABRT 
Exception Codes: #0 at 0x197fb7140 
Crashed Thread: 3 

Application Specific Information: 
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An NSManagedObjectContext cannot refresh objects in other contexts.' 

Last Exception Backtrace: 
0 CoreFoundation      0x0000000182a98f48 __exceptionPreprocess + 124 
1 libobjc.A.dylib      0x000000019764bf80 objc_exception_throw + 52 
2 CoreData        0x0000000182786898 -[NSManagedObjectContext refreshObject:mergeChanges:] + 1320 
3 CJournal        0x00000001001729c4 __75-[ContactsSyncController loadContactImagesAndLinksWithPermissionWithBlock:]_block_invoke_2 (ContactsSyncController.m:102) 
4 CoreData        0x00000001827dc900 developerSubmittedBlockToNSManagedObjectContextPerform + 192 
5 libdispatch.dylib     0x0000000197e696a8 _dispatch_client_callout + 12 
6 libdispatch.dylib     0x0000000197e74954 _dispatch_barrier_sync_f_invoke + 96 
7 CoreData        0x00000001827dc7e8 -[NSManagedObjectContext performBlockAndWait:] + 248 
8 CJournal        0x00000001001728bc __75-[ContactsSyncController loadContactImagesAndLinksWithPermissionWithBlock:]_block_invoke (ContactsSyncController.m:97) 
9 libdispatch.dylib     0x0000000197e696e8 _dispatch_call_block_and_release + 20 
10 libdispatch.dylib     0x0000000197e696a8 _dispatch_client_callout + 12 
11 libdispatch.dylib     0x0000000197e756ec _dispatch_queue_drain + 860 
12 libdispatch.dylib     0x0000000197e6d1ac _dispatch_queue_invoke + 460 
13 libdispatch.dylib     0x0000000197e696a8 _dispatch_client_callout + 12 
14 libdispatch.dylib     0x0000000197e77b40 _dispatch_root_queue_drain + 2136 
15 libdispatch.dylib     0x0000000197e772dc _dispatch_worker_thread3 + 108 
16 libsystem_pthread.dylib    0x000000019807d470 _pthread_wqthread + 1088 
17 libsystem_pthread.dylib    0x000000019807d020 start_wqthread + 0 

任意のアイデア?

+0

あなたの個人オブジェクトは、他のCoreDataオブジェクトを参照してい:?私が思いついた解決策はmanagedObjectContextが同じだった、とだけにしてオブジェクトを更新かどうかを確認することでしたかあなたのインスタンスはかなり安全に見えますが、何らかの形で別のコンテキストで何かに接続されていますか? – deanWombourne

+0

いいえ、そうは思わない...人からの関係がありますが、このコンテキストではフォルトとしてロードする必要があります。私は確認するためにさらに見ていきます。しかし、私の感心しているのは、別のプロセスが永続ストア(およびそれを使用して、メインの管理オブジェクトコンテキスト)をリセットする可能性があるということです。潜在的に問題を説明できるでしょうか? –

+0

@ZSそうです。 – Mundi

答えて

0

問題は、特別な状況では、アプリケーション内の何かがpersistentStoreを置き換えて、managedContextをリセットし、loadContactReferenceAndImageとrefreshObjectの呼び出しが両方ともperformBlockAndWait内にあっても問題ではないということでした。

 [self.backgroundContextImage performBlockAndWait: ^{ 
       [person loadContactReferenceAndImage]; 

       // MOC could have been updated by another thread 
       if (person.managedObjectContext == self.backgroundContextImage) { 
        [self.backgroundContextImage refreshObject: person mergeChanges:NO]; 
       } 

     }]; 
関連する問題