1

私のアプリでは、バックグラウンドで Core Data の作業を常に行っています。

Testflight は、現在ログインしている環境オブジェクトを Core Data から取得する特定のフェッチで多くのクラッシュを報告しています (複製できません)。

- (Environment *)getActiveEnvironment
{
    AppDelegate *ad = [AppDelegate sharedAppDelegate];
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
    [context setParentContext:ad.managedObjectContext];
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Environment" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    
    NSError *error;

    //crash points to this line
    NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
    
    Environment *tempE = nil;
    if(items.count > 0)
    {
        for(Environment *e in items)
        {
            if(!e.token && !e.url)
            {
                break;
            }
            
            Environment *mainContextTv = (Environment *)[ad.managedObjectContext objectWithID:e.objectID];
            if(e.activeValue)
                 tempE = mainContextTv;                
        }  
    }

    return tempE;
}

Testflight から受け取ったクラッシュ スタックは次のとおりです。

0   Tower-iSales-Tab    0x002b37b2  testflight_backtrace
1   Tower-iSales-Tab    0x002b2e4a  TFSignalHandler
2   libsystem_platform.dylib    0x39144722  _sigtramp
3   CoreData    0x2e1b8cec  _perform
4   CoreData    0x2e1c30f4  -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]
5   CoreData    0x2e13477a  -[NSManagedObjectContext executeFetchRequest:error:]
6   Tower-iSales-Tab    0x000c7082  -[MySingleton getActiveEnvironment] in MySingleton.m on Line 379
7   Tower-iSales-Tab    0x000c73f8  -[MySingleton getToken] in MySingleton.m on Line 416
8   Tower-iSales-Tab    0x0020c476  -[NetworkManager getPathForViewName:useTimeStamp:timeStamp:index:counter:] in NetworkManager.m on Line 699
9   Tower-iSales-Tab    0x0020aa5a  __70-[NetworkManager checkForDataFilesShouldEmptyQueue:isInitialDownload:]_block_invoke167 in NetworkManager.m on Line 415
10  libdispatch.dylib   0x3901b8fa  _dispatch_barrier_sync_f_invoke
11  Tower-iSales-Tab    0x0020a33e  __70-[NetworkManager checkForDataFilesShouldEmptyQueue:isInitialDownload:]_block_invoke113 in NetworkManager.m on Line 335
12  libdispatch.dylib   0x39017102  _dispatch_call_block_and_release
13  libdispatch.dylib   0x3901c7e4  _dispatch_root_queue_drain
14  libdispatch.dylib   0x3901c9d0  _dispatch_worker_thread2
15  libsystem_pthread.dylib 0x39146dfe  _pthread_wqthread
16  libsystem_pthread.dylib 0x39146cc3  start_wqthread

私ができることではなく、キュータイプを に設定することを提案するこの回答を読みましたが、これは簡単に複製できるクラッシュではないので、このクラッシュが発生することを確認したいと思います。NSPrivateQueueConcurrencyTypeNSConfinementConcurrencyType

その答えはperformBlockAndWait、バックグラウンドフェッチにブロックを使用することも提案していますが、私の機能ではどうすればよいでしょうか? オブジェクトを返す必要がありEnvironmentます。アプリ全体でこの関数を使用しています。

ありがとう

4

2 に答える 2

2

おそらく、この問題の原因は、NSManagedObjectContext作成されたスレッドとは別のスレッドから にアクセスしていることです。

ゴールデン ルール: 常にNSManagedObjectContext作成したスレッドから にアクセスします。

したがって、MOC が同じスレッドから一貫してアクセスされていることを確認する必要があります。

偶発的NSPrivateQueueConcurrencyTypeに関連している可能性があり、それを行うことで問題が解決する可能性があると思いますが(コードが正確に何をしているかによって異なります)、ここでの中心的な問題ではない可能性があります.

補足: 永続オブジェクト ストアには同じ要件はなく、スレッド セーフです (多くの場合、同じ永続オブジェクト ストアを使用する複数の MOC があります)。

于 2013-10-24T14:53:24.337 に答える