0

按照Concurrency with Core Data Guide臨時管理對象上下文,你不應該節省的NSManagedObjectContext在後臺線程,因爲它是可能的應用程序退出保存完成之前,因爲線程分離。保存在後臺排隊

如果我理解正確的話,這意味着這樣的事情是不正確

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [tempContext setParentContext:[[MyDataManager sharedInstance] mainContext]; 
    [tempContext performBlockAndWait:^{ 
     //Do some processing 
     NSError* error; 
     [tempContext save:&error]; 
    }]; 
}); 

我的第一本能是隻保存在它結束時的主隊列的背景下,但managedObjectContexts應該是線程安全。下面的東西能夠解決問題還是有更好的解決方案?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
    NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [tempContext setParentContext:[[MyDataManager sharedInstance] mainContext]; 
    [tempContext performBlockAndWait:^{ 
     //Do some processing 
    }]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [tempContext performBlockAndWait:^{ 
      NSError* error; 
      [tempContext save:&error]; 
     }]; 
    }); 
}); 

回答

1

第一:

在你的第一個例子:
[context save:...]應該在上下文的performBlockAndWait:塊來完成。
此外,如果您使用的背景下,你可以簡單地調用它的performBlock:方法,因爲它已經使用GCD的調度,所以它看起來像:

NSManagedObjectContext* tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
[tempContext setParentContext:[[MyDataManager sharedInstance] mainContext]; 
[tempContext performBlock:^{ 
    //Do some processing 
    NSError* error; 
    [tempContext save:&error]; 
}]; 

其次:

「保存在後臺線程容易出錯」(正如我所知道的那樣並理解它)意思是:
您可以保存在後臺,但不能保證您調用的保存將運行到完成,如果應用程序退出(數據庫仍然有效,或者可以回滾到預局部保存狀態)。
==>
如果使用後臺保存,不要以爲一個保存操作2個應用程序執行之間完成。

三(只是強調):
請勿使用私人隊列的語境,不performBlock:performBlockAndWait:
==>
你的第二個例子會導致意外的行爲

+0

確定調用保存performBlock是有道理的,但是有沒有辦法確保在應用程序退出之前保存完整的背景? – adamF

+0

正如我在第二點中提到的那樣,NO。這是主線程保存和後臺保存的區別。如果您有必須保存的重要信息,請在主線程上執行。 –

+0

謝謝,但我最初的問題是我該怎麼做到這一點?你說我的第二個例子會導致意外的行爲。是因爲我沒有使用performBlock,還是因爲它是在主線程上執行的私有隊列上下文?請看我編輯的問題。在主線程上保存的正確方法是什麼? – adamF