首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ALAssetsLibrary,等到assetForURL完成

ALAssetsLibrary,等到assetForURL完成
EN

Stack Overflow用户
提问于 2014-03-18 10:03:51
回答 4查看 2.2K关注 0票数 1

我有一个包含图像的数组,该数组对应于资产库中的图像,在执行特定任务之前,我需要获取所有这些图像。做这件事最好的方法是什么?我应该使用NSNotificationCenter还是使用块更好,如果是这样的话,有什么例子吗?

下面是我的代码:

代码语言:javascript
复制
- (IBAction)buttonClicked:(id)sender {

    NSMutableArray* images = [NSMutableArray array];
    //Need to loop through the takenImagesURLArray
    for (NSURL *imageURL in takenImagesURLArray) {
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library assetForURL:imageURL
                 resultBlock:^(ALAsset *asset) {
                     if (asset) {
                         NSLog(@"HAS ASSET: %@", asset);
                         UIImage *image = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
                         [images addObject:image];
                     } else {
                         NSLog(@"Something went wrong");
                     }
                 }
                failureBlock:^(NSError *error) {
                    NSLog(@"Something went wrong, %@", error);
                }];
    }
    //This will of course be called before images is ready
    [self doCertainTaskWith: images];
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-03-18 10:32:58

你可以用中央总台来处理这个。

但是首先,将ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];移出for-循环,因为它可以重用。

现在是真正的密码。看起来会是这样的:

代码语言:javascript
复制
dispatch_group_t dgroup = dispatch_group_create(); //0

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

for (NSURL *imageURL in urls) {

    dispatch_group_enter(dgroup); // 1

        [library assetForURL:imageURL resultBlock:^(ALAsset *asset) {
            if (asset) {
                NSLog(@"HAS ASSET: %@", asset);
                UIImage *image = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]];
                [images addObject:image];

                dispatch_group_leave(dgroup); //2

            } else {
                NSLog(@"Something went wrong");
                dispatch_group_leave(dgroup);
            }
        } failureBlock:^(NSError *error) {
            NSLog(@"Something went wrong, %@", error);
            dispatch_group_leave(dgroup);
    }];

}

dispatch_group_notify(dgroup, dispatch_get_main_queue(), ^{ //3

    NSLog(@"Do something with %d images", [images count]);

});

代码说明(请遵循代码中的注释)

  1. 我们成立了一个小组,帮助我们实现我们想要的。把它想象成一个简单的列表。
  2. 我们将每一项输入到组中。把它看作是增加对象上的retain支柱,在本例中是我们的组。
  3. 当我们完成的时候,我们告诉它离开小组。把它看作是调用对象上的release
  4. 当计数返回到组中的0时,所有的任务都已经完成。无论你需要对图像做什么,都可以在这里完成。
票数 3
EN

Stack Overflow用户

发布于 2014-03-18 10:10:43

使用一个简单的计数器,在块外部创建并在块内更新(无论成功还是失败)。当计数器值与图像计数匹配时,您知道执行最后一条语句(它应该在资产库结果块内的if语句中)。

票数 0
EN

Stack Overflow用户

发布于 2014-03-18 10:21:16

您所描述的块方法很可能会在它们全部获取之前调用它们来做一些事情。您可以在块操作完成后在完成处理程序中调用它们。

我得承认我自己也弄糊涂了。我用来帮忙。

简而言之,我会重新安排你所做的,将循环放入块中。这里有一些语法上很糟糕的代码来说明..。

代码语言:javascript
复制
- (void)processImagesWithCompletionHandler:void (^)(NSArray*))completion {
    dispatch_async(dispatch_get_global_queue, ^{ //runs in background thread
       **for loop that gets images and adds to an array called images**
       dispatch_async(dispatch_get_main_queue, ^{ //runs on main queue as it may affect the UI
          completion(images);
       });
    });
}

然后,您可以使用以下方法进行调用:

代码语言:javascript
复制
[self processImagesWithCompletionHandler:^void (NSArray *images) {
   self doCertainTaskWith:images];
}];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22475947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档