等待信号量完成writeImageToSavedPhotosAlbum的块

时间:2014-07-01 21:37:58

标签: objective-c ios7 semaphore alassetslibrary

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

没有信号量,方法就可以完美运行。但是我没有收到资产URL。

+ (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方法的方法:

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

}

1 个答案:

答案 0 :(得分:5)

等待。永远不要做你正在做的事。您无法理解“异步”的含义。这意味着当你完成块中的时,你会被回叫。所以 是你执行下一步的地方。

请勿尝试从在异步完成块中获取该值的方法返回值。

所以,在这里,在writeImageToSavedPhotosAlbum:的完成区块中, 是您收到retAssestURL的地方。因此,如果还有一个步骤,现在执行此操作,那里,在完成块中 。这可能涉及调用另一种方法或任何你喜欢的方法,但关键是,事情现在将以正确的顺序发生。

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