1

次のコードでアセット ライブラリにクエリを実行しています

ALAssetsLibrary *assetsLibrary = [self defaultAssetsLibrary];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    NSMutableArray *tmpAssets = [@[] mutableCopy];
    [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if(result)
        {
            [tmpAssets addObject:result];
        }
    }];

    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
    finished([[tmpAssets sortedArrayUsingDescriptors:@[sort]]  mutableCopy]);

} failureBlock:^(NSError *error) {
    finished(@[]);
    NSLog(@"Error loading images %@", error);
}];

ただし、すべてのアセットを取得していないようです。外部ソースから iPhone に画像を追加すると、これらは上記のコードから受け取ったアセットのリストに表示されません...他のすべてのように見えるものを取得していますが. フレームワークの制限ではないかと思いましたが、instagram を使用すると、アプリにない写真が表示されていることに気付きました...どのようにすべてのタイプのアセット "ALassetsGroupAll" を取得するのに十分ではありませんか?

4

2 に答える 2

0

問題は、仕組みを理解していないことですenumerateAssetsUsingBlock:非同期です。

これが何を意味するのかを理解するために、いくつかの数字を使用してコードを分割してみましょう。

// (1)
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
    // (2)
    if(result)
    {
        [tmpAssets addObject:result];
    }
}];
// (3)
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
finished([[tmpAssets sortedArrayUsingDescriptors:@[sort]]  mutableCopy]);

問題は、3 が 2 より前に実行されることです。したがって、まだ何も入っtmpAssetsていません。

それで、あなたはこれについて何をすべきですか?さて、このメソッド (および同様に機能する他の A​​LAssets メソッド) は、非常に奇妙で特別な方法で動作します。つまり、nil 引数を使用して、ブロックを1 回余分に呼び出します。(nil テストを行っているので、これに気付いたようですが、その意味が理解できていません。) あなたの仕事は、nil パラメータをテストすることです。パラメータが nil の場合、これが最後の余分な呼び出しであり、これでクリーンアップを行うことができます。したがって、次のようになります。

// (1)
[group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
    // (2)
    if(result)
    {
        [tmpAssets addObject:result];
    }
    else
    // (3) // aha, finished, this is the extra time through
    {
        // NOW do something with tmpAssets!
    }
}];
于 2014-05-28T03:08:47.097 に答える
-1

完成したブロックへの複数の呼び出しを使用して個別にグループを作成するのではなく、すべてのグループからすべてのアセットを単一の配列に追加する必要があるようです。

-(NSArray *)allAssets {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    NSMutableArray *allAssets = [@[] mutableCopy];

    [[self defaultAssetsLibrary] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            if(result)
                [tmpAssets addObject:result];
        }];

        dispatch_semaphore_signal(semaphore);
    } failureBlock:^(NSError *error) {
        NSLog(@"Error loading images %@", error);
        dispatch_semaphore_signal(semaphore);
    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO];
    return [tmpAssets sortedArrayUsingDescriptors:@[sort]];
}
于 2014-05-28T02:20:20.927 に答える