3

写真ライブラリからすべての画像を取得しようとしています。問題は、メソッド[ALAssetsGroup enumerateAssetsUsingBlock:]が非同期であるため、アセットを使用しようとするまでに、列挙子がアセット配列への入力を開始していないことです。これが私のコードです:

        NSMutableArray* photos = [[NSMutableArray alloc] init];

        void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if(result != nil) {
                if(![assetURLDictionaries containsObject:[result valueForProperty:ALAssetPropertyURLs]]) {
                    if(![[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) {
                        UIImage* img = [UIImage imageWithCGImage:[[result defaultRepresentation] fullScreenImage]];

                        MyPhoto *photo;
                        photo = [MyPhoto photoWithImage:img];
                        [photos addObject:photo];
                    }
                }
            }
        };

        [[assetGroups objectAtIndex:1] enumerateAssetsUsingBlock:assetEnumerator];

        self.photos = photos;
        NSLog(@"Self.Photos %@", self.photos);

このブロックが実行された後self.photosは空です。列挙子ブロックが別のスレッドで実行さphotosれ、割り当てで空であるためだとself.photos = photos思いますか? 何か案は?

4

1 に答える 1

1

おっしゃる通り非同期なので、最終代入は非同期で行う必要があります。列挙子がアセットを使い果たすと、結果として nil が返されます。これは、列挙の最後のアクションとして 1 回だけ発生します。したがって、推奨されるパターンは次のとおりです。

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
    if(result != nil) {
        // ... process result ...
        [photos addObject:photo];
    }
    else {
        // terminating
        self.photos = photos
        NSLog(@"Self.Photos %@", self.photos);

        // you can now call another method or do whatever other post-assign action here
    }
};
于 2013-02-25T18:09:27.553 に答える