2012-05-04 44 views
8

當使用NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType類型NSManagedObjectContext, 是否可以安全地在同一個上下文中執行嵌套的performBlock調用?嵌套performBlock:在NSManagedObjectContext

[backgroundContext performBlock:^{ 
    NSFetchRequest *myRequest = ...; 
    __block NSArray *result= nil; 
    [backgroundContext performBlockAndWait:^{ 
     results = [backgroundContext executeFetchRequest:myRequest error:NULL]; 
    }]; 
}]; 

這似乎是愚蠢的,但我有很多其封裝executeFetchRequest來電助手方法現有的代碼庫。我不想對調用者是否已經使用performBlock做出假設。 例如:

-(void)updateObjects:(BOOL)synchronous 
{ 
    if (YES == synchronous) 
     [self fetchHelper]; 
    else 
    { 
     [backgroundContext performBlock:^{ 
      [self fetchHelper]; 
     }]; 
    } 
} 

-(NSArray*)fetchHelper 
{ 
    [self.backgroundContext performBlockAndWait:^{ 
     //Fetch the objects... 
     [self.backgroundContext executeFetchRequest: (...)]; 
    }]; 
} 

我試過了,它的工作原理。但我已經學會了(很難)對Core Data和多線程非常小心。

回答

8

是,performBlockAndWait是折返。直接從Apple的發行說明...

核心數據使用新選項正式化了 NSManagedObjectContext類的併發模型。當你創建一個 情況下,你可以指定它使用併發模式: 線程限制,私有調度隊列,或主調度 隊列。所述NSConfinementConcurrencyType選項提供相同 行爲之前5.0存在iOS上的版本,並且是 默認。將消息發送到使用隊列 關聯創建的上下文時,如果您的代碼尚未在該隊列上執行(對於主隊列類型爲 ),或者在performBlock的範圍內,則必須使用performBlock:或performBlockAndWait: 方法。 ..調用 (用於私有隊列類型)。在傳遞給那些 方法的塊中,可以自由使用NSManagedObjectContext的方法。 performBlockAndWait:方法支持API重入。該performBlock: 方法包括一個自動釋放池,並調用完成後 processPendingChanges方法。

+0

什麼performBlock,是重入嗎? – malhal

+0

這不是,這是在會議中討論。如果您調用performBlock,您的請求將排隊,因爲它是異步的。 –

+0

只是要清楚,OP在第二位代碼中所做的是可以做到的,但是如果兩種方法都有「performBlock」,會導致問題?這是正確的方式來看待這個? – hokkuk