2011-06-20 27 views
1

在iOS 4.x上,我嘗試枚舉設備上的所有照片,當完成後,再在相同的方法中處理該列表。在主線程中輪詢時,enumerateGroupsWithTypes將不會執行塊

由於enumerateGroupsWithTypes塊在另一個線程上異步運行,我無法看到如何繼續執行主線程以防止繼續執行,所以我開始進行進一步處理直到準備就緒的解決方案是輪詢我的照片數組收集直到它看到它已經完成填充NSNull對象的結尾。

在iOS 4.0上它工作正常 - 輪詢繼續,因爲其他線程枚舉照片,然後在完成後繼續執行主線程。在iOS 4.1+上,輪詢是如何阻止其他線程執行任何塊的,因此輪詢陷入無限循環。

有沒有更好的方式來實現這一點,而不是通過將進一步處理分解爲枚舉塊可以調用的另一種方法來包含枚舉的異步特性?

積分:爲什麼我的輪詢方法在4.0而不是4.1+上工作?

NSMutableArray *photos = [NSMutableArray new]; 

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) { 
    if(result != NULL) { 
     [photos addObject:result]; 
    } 
}; 
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) { 
    if(group != nil) 
     [group enumerateAssetsUsingBlock:assetEnumerator]; 
    else 
     [photos addObject:[NSNull null]]; 
}; 

ALAssetsLibrary *library = [ALAssetsLibrary new]; 

[library enumerateGroupsWithTypes:ALAssetsGroupAll 
         usingBlock:assetGroupEnumerator 
        failureBlock:^(NSError *error) { 
         NSLog(@"%@", error); 
        }]; 

// keep polling until the photos have all been enumerated 
// (NSNull is the last 'photo' added) 
while (![photos count] || ![[photos objectAtIndex:[photos count]-1] isEqual:[NSNull null]]); 

// ... further processing ... 

回答

1

更好的辦法是讓你的塊開球的進一步處理(例如,使用performSelectorOnMainThread:withObject:waitUntilDone:),而不是具有用於它的主線程輪詢。

我不能肯定地說爲什麼它在4.0中工作,在4.1中失敗。有可能在4.1中它在某些情況下不再是異步的(例如,當用戶不需要提示時),或者在4.1中它在開始後臺任務之前等待主線程上的回調,或者在你的4.1設備或模擬器實例試圖請求許可(並掛起,因爲你的主運行循環被阻止),如果你還沒有授權它訪問早期測試中的照片庫,它也會在4.0上失敗。

+0

謝謝。但是我發現令人沮喪的是,我無法將這一切全部編碼成單一方法。 –

相關問題