问题
I'm trying to pull all images from the photos library. The problem is that the method [ALAssetsGroup enumerateAssetsUsingBlock:]
is asynchronous so by the time I'm trying to use the assets the enumerator has not started populating my assets array. Here's my code:
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);
After this block runs self.photos
is empty. I'm guessing it's because the enumerator block executes in another thread and photos
is empty in the assignment self.photos = photos
? Any ideas?
回答1:
As you say, it's asynchronous, so you need to do the final assignment asynchronously. When the enumerator has exhausted the assets, it will return nil as the result. This happens exactly once and always as the last action of the enumeration. So the recommended pattern is:
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
}
};
来源:https://stackoverflow.com/questions/13211003/how-to-store-assets-with-asynchronous-enumerator-in-alassetslibrary