Ожидание завершения блока writeImageToSavedPhotosAlbum от семафора
В моем приложении я открываю камеру сборщиком, и после того, как фотография была сделана, я бы хотел сохранить ее следующим способом, используя библиотеку ресурсов. Метод зависает после вызова 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;
}
И это метод, где я называю 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 ответ
Не жди Никогда, никогда не делай то, что делаешь. Вы не понимаете, что такое "асинхронный". Это означает, что вам перезвонят, когда все закончится в блоке завершения. Вот где вы выполните следующий шаг.
НЕ пытайтесь вернуть значение из метода, который получает это значение в блоке асинхронного завершения.
Итак, здесь, в writeImageToSavedPhotosAlbum:
блок завершения, где вы получаете retAssestURL
, Так что, если есть дальнейший шаг, теперь сделайте это там, в блоке завершения. Это может включать в себя вызов другого метода или что угодно, но дело в том, что теперь все будет происходить в правильном порядке.
И, прежде всего, НЕ используйте семафоры (или другие хитрости), чтобы попытаться превратить асинхронный в синхронный. Асинхронные вещи являются асинхронными по причине. Используйте рамки, не боритесь с этим. (На самом деле, то, что вы делаете с семафорами здесь, это не просто борьба с фреймворком, а плевок в глаза.)