1

我正在尝试挑选一些相机胶卷元数据。当我枚举资产时,我似乎无法检索任何信息并获得一个空数组。有没有我错过的步骤?

我的代码:

assets = [[NSMutableArray array] init]; 

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) {
    if(asset != NULL) {
        [assets addObject:asset];
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    }
};

void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) =  ^(ALAssetsGroup *group, BOOL *stop) {
    if(group != nil) {
        [group enumerateAssetsUsingBlock:assetEnumerator];
    }
};

library = [[ALAssetsLibrary alloc] init];

[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos 
                       usingBlock:assetGroupEnumerator
                     failureBlock: ^(NSError *error) {
                         NSLog(@"Failed.");
                     }];    

NSLog(@"%@", assets); //prints an empty array
4

3 回答 3

4

Midhun MP 是正确的,您没有等待异步枚举完成。在这种情况下,您有异步块调用其他异步块,因此要知道所有枚举何时完成并不简单。

如果您想知道何时完成,并最终得到一个包含所有枚举资产的数组,您可以使用 dispatch_groups。这是您可以做到这一点的一种方法(我包含了多个 ALAssetGroup 类型以表明这可以与多个专辑一起使用):

dispatch_group_t loadingGroup = dispatch_group_create();
NSMutableArray * assets = [[NSMutableArray array] init];
NSMutableArray * albums = [[NSMutableArray array] init];

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) {
    if(index != NSNotFound) {
        [assets addObject:asset];
        dispatch_async(dispatch_get_main_queue(), ^{ });
    } else {
        dispatch_group_leave(loadingGroup);
    }
};


void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) =  ^(ALAssetsGroup *group, BOOL *stop) {
    if(group != nil) {
        [albums addObject: group];
    } else {
         NSLog(@"Found %d albums", [albums count]);
         // album loading is done
        for (ALAssetsGroup * album in albums) {
            dispatch_group_enter(loadingGroup);
            [album enumerateAssetsUsingBlock: assetEnumerator];
        }
        dispatch_group_notify(loadingGroup, dispatch_get_main_queue(), ^{
            NSLog(@"DONE: ALAsset array contains %d elements", [assets count]);
        });
    }
};

ALAssetsLibrary * library = [[ALAssetsLibrary alloc] init];

[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos | ALAssetsGroupAlbum
                   usingBlock:assetGroupEnumerator
                 failureBlock: ^(NSError *error) {
                     NSLog(@"Failed.");
                 }];

(在这个例子中,添加各种块是安全的assetsalbums因为枚举都发生在主线程上。)

于 2012-11-09T14:26:25.357 回答
0

如果您在 iOS 6 上运行此程序,则可能是用户拒绝了您的应用程序访问资产库的访问权限。如果是这种情况,failureBlock则调用 。

另请注意,它usingBlock是异步调用的,因此您尝试记录assets为时过早。您应该将该NSLog语句移到枚举块的末尾。

从文档中enumerateGroupsWithTypes:usingBlock:failureBlock:

通过执行枚举块将结果一一传递给调用者。

此方法是异步的。枚举组时,可能会要求用户确认应用程序对数据的访问;但是,该方法会立即返回。您应该对 enumerationBlock 中的资产执行任何您想要的工作。

如果用户拒绝访问应用程序,或者不允许任何应用程序访问数据,则调用 failureBlock。

于 2012-11-08T23:01:11.537 回答
0

您的 NSLog 将始终显示一个空数组,因为 NSLog 语句将在完成异步枚举块之前工作。

解决方案:

首先检查您的照片库是否为空。然后在里面添加NSLog:

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) {
    if(asset != NULL) {
        [assets addObject:asset];
        NSLog(@"Asset : %@", asset);
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    }
};
于 2012-11-09T03:55:29.617 回答