iOS 4.x では、デバイス上のすべての写真を列挙しようとしています。それが完了したら、同じ方法でそのリストをさらに処理します。
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 ...