我試圖以同步的iOS5以下代碼:我應該如何使用GCD dispatch_barrier_async iOS中(之前似乎沒有和其他後塊來執行)
- 對象具有使一個HTTP請求的方法從中 得到一些數據,包括圖片網址
- 一旦數據到達時,文本數據被用來填充 CoreData模型
- 在同一時間,第二個線程分派異步下載 圖片;此線程將通過KVO發送信號給viewController,此時 圖像已被緩存並可在CoreData模型中使用。
- 由於圖片下載需要一段時間,我們馬上將 的CoreData對象具有除圖片外的所有屬性給 作爲調用者。
- 另外,當第二個線程完成下載時,可以保存CoreData型號 。
這是(簡化)代碼:
- (void)insideSomeMethod
{
[SomeHTTPRequest withCompletionHandler:
^(id retrievedData)
{
if(!retrievedData)
{
handler(nil);
}
// Populate CoreData model with retrieved Data...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]];
aCoreDataNSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL];
});
handler(aCoreDataNSManagedObject);
[self shouldCommitChangesToModel];
}];
}
- (void)shouldCommitChangesToModel
{
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSError *error = nil;
if(![managedObjectContext save:&error])
{
// Handle error
}
});
}
但是發生了什麼事情是,阻擋基於保存塊的圖像加載塊之前總是執行。也就是說,
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSError *error = nil;
if(![managedObjectContext save:&error])
{
// Handle error
}
});
前執行:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]];
aCoreDataNSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL];
});
所以,很顯然,我不是真的調度圖像加載塊障礙之前,或阻擋會等到圖像加載塊完成在執行之前(這是我的意圖)。
我在做什麼錯?如何確保圖像加載塊在阻擋塊之前排隊?
我自己想了好幾次,但之後,蘋果公司的文檔沒有說明在iOS中我們不能真正創建自己的隊列嗎?所以如果我「創造」一個,我實際上只是獲得一個全球化之一的別名? – SaldaVonSchwartz
我相信,從ios5開始,您可以創建您的調度隊列。 – timthetoolman
是的,我剛剛嘗試過它,現在它工作。我會發誓我讀了我們無法創建自己的或創建它們僅僅返回全局的一個,這就是爲什麼我只是在上面的代碼中明確地使用了全局的全局。 – SaldaVonSchwartz