等待信号量完成writeImageToSavedPhotosAlbum的块

Mor*_*s78 0 semaphore objective-c alassetslibrary ios7

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

没有信号量,方法可以完美地工作.但是我没想到会收到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;
}
Run Code Online (Sandbox Code Playgroud)

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

- (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...

}
Run Code Online (Sandbox Code Playgroud)

mat*_*att 5

千万不能等待.永远不要做你正在做的事.您无法理解"异步"的含义.这意味着当你在完成块中全部结束时,你会被回叫.所以是你执行下一步.

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

所以,在这里,在writeImageToSavedPhotosAlbum:完成块,是你收到的地方retAssestURL.所以,如果有进一步的步骤,现在做到这一点,在那里,在完成块.这可能涉及调用另一种方法或任何你喜欢的方法,但关键是,事情现在将以正确的顺序发生.

最重要的是,不要使用信号量(或其他技巧)来尝试将异步转换为同步.异步事情是异步的原因.使用框架,不要打架.(实际上,你在这里使用信号量所做的不仅仅是与框架作斗争,而是随地吐痰.)