繁体   English   中英

ALAssetsLibrary,等到assetForURL完成

[英]ALAssetsLibrary, wait until assetForURL is finished

我有一个带有图像的数组,它与assetslibrary中的图像相对应,我需要在执行某个任务之前获取所有这些图像。 这是最好的方法吗? 我应该使用NSNotificationCenter还是更好地使用块,如果是这样,任何例子?

这是我的代码:

- (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];
}

你可以使用Grand Central Dispatch。

但首先,移动ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 在for循环之外,因为它可以重用。

现在为真正的代码。 它看起来像这样:

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时,所有任务都已完成。 无论您需要对图像做什么,都可以在这里完成。

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

您概述的阻止方法可能会在获取所有内容之前调用它们。 您可以调用在块操作完成后执行的完成处理程序中处理它们。

我承认自己会遇到障碍。 我用这个来帮忙。

简而言之,我会重新安排你所做的将循环置于块中。 这里有一些语法上可怕的代码来说明......

- (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);
       });
    });
}

然后你可以用以下方法调用它:

[self processImagesWithCompletionHandler:^void (NSArray *images) {
   self doCertainTaskWith:images];
}];

Wain在代码中的答案

- (IBAction)buttonClicked:(id)sender {
    __block NSInteger assetCount = 0;
    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");
                     }
                     assetCount++;
                     if (assetCount == takenImagesURLArray.count)
                     {
                         [self doCertainTaskWith:images];
                     }
                 }
                failureBlock:^(NSError *error) {
                    NSLog(@"Something went wrong, %@", error);
                }];
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM