通过信号量等待 writeImageToSavedPhotosAlbum 的完成块 [英] Wait for completion block of writeImageToSavedPhotosAlbum by semaphore

查看:20
本文介绍了通过信号量等待 writeImageToSavedPhotosAlbum 的完成块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我通过选择器打开相机,在拍摄照片后,我想通过以下方法保护资产库.该方法在调用 writeImageToSavedPhotosAlbum 后冻结.

In my app I open the camera by a picker and after the photo has been taken I'd like to safe it by the following method the assets library. The method freezes after the call of the writeImageToSavedPhotosAlbum.

没有信号量,这些方法可以完美运行.但比我想念收到 assetURL.

Without the semaphores the methods work perfectly. But than I miss to receive the assetURL.

+ (NSURL*)safeImageToAssetsLibrary:(UIImage *)image metadata:(NSDictionary *)metadata
{
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    __block NSURL *retAssestURL = nil;

    dispatch_semaphore_t semaWaitingForSafeImage = dispatch_semaphore_create(0);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // safe the image to the assests library
    NSLog(@"Safe image to asssets library...");

    dispatch_async(queue, ^{
        [library writeImageToSavedPhotosAlbum:image.CGImage metadata:metadata completionBlock:^(NSURL *assetURL, NSError *error) {

            if (error) {
                NSLog(@"Image could not be safed to the assets library: %@", error);
                retAssestURL = nil;
            }
            else {
                NSLog( @"Image safed successfully to assetURL: %@", assetURL);
                retAssestURL = assetURL;
            }

            dispatch_semaphore_signal(semaWaitingForSafeImage);
        }];
    });

    dispatch_semaphore_wait(semaWaitingForSafeImage, DISPATCH_TIME_FOREVER);

    return retAssestURL;
}

这是我调用 safeImageToAssetsLibrary 方法的方法:

And this is method where I call the safeImageToAssetsLibrary method:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [picker dismissViewControllerAnimated:YES completion:NULL];

    // get chosen image and add thumbnail to collection view
    NSURL *imageUrl        = info[UIImagePickerControllerReferenceURL];
    UIImage *chosenImage   = info[UIImagePickerControllerOriginalImage];

    // safe image to photo library if the camera has been used
    if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
        imageUrl = [BaseImageHandler safeImageToAssetsLibrary:chosenImage metadata:info[UIImagePickerControllerMediaMetadata]];
    }

    // UPDATE View and Core Data here...

}

推荐答案

不要等待.永远,永远不要做你正在做的事情.您无法理解异步"是什么意思.这意味着当它在完成块中全部结束时,你会被回调.所以就是您执行下一步的地方.

Do not wait. Never, never do what you are doing. You are failing to understand what "asynchronous" is about. It means that you are called back when it's all over in the completion block. So that is where you perform the next step.

不要尝试从在异步完成块中获取该值的方法返回一个值.

所以,在这里,在 writeImageToSavedPhotosAlbum: 的完成块中,那个就是您接收 retAssestURL 的地方.因此,如果还有进一步的步骤,现在就去做,在那里,在完成块中.这可能涉及调用其他方法或任何您喜欢的方法,但重点是,现在事情会以正确的顺序发生.

So, here, in writeImageToSavedPhotosAlbum:'s completion block, that is where you receive retAssestURL. So if there is a further step, now do it, there, in the completion block. This could involve calling another method or whatever you like, but the point is, things will now happen in the correct order.

最重要的是,不要使用信号量(或其他技巧)来尝试将异步变为同步.异步事物是有原因的.使用框架,不要对抗它.(实际上,您在这里使用信号量所做的不仅仅是与框架作斗争,而是向其眼睛吐口水.)

And above all, Do NOT use semaphores (or other trickery) to try to turn asynchronous into synchronous. Asynchronous things are asynchronous for a reason. Use the framework, don't fight it. (Actually, what you are doing with semaphores here is not just fighting the framework but spitting in its eye.)

这篇关于通过信号量等待 writeImageToSavedPhotosAlbum 的完成块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆