4

スレッド間でタスクを割り当てる方法、または非同期でディスパッチする方法を学ぶだけです。ビューに「触れる」操作はすべてメインスレッドで実行する必要があることを理解しています。どうですか:UIImageWriteToSavedPhotosAlbumこれはバックグラウンドスレッドで実行できると思いますが、私は間違っていますか?

また、バックグラウンドスレッドで実行する必要がある場合、一方がUIImageを保存し、もう一方がビューからUIImageを保存するため、以下の2つの呼び出しに違いはありますか?

UIImageWriteToSavedPhotosAlbum(_someUIImage ,nil,nil,nil);

UIImageWriteToSavedPhotosAlbum(_imageView.image ,nil,nil,nil);

ちなみに、私はこのセットアップを使用して、メインスレッドでHUDを実行し、バックグラウンドでタスクを実行しています。これが私の意図です。

[HUD_code showMessage:@"saving image"];
dispatch_queue_t concurrentQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(concurrentQueue, ^{
        UIImageWriteToSavedPhotosAlbum(someUIImage ,nil,nil,nil);
            dispatch_async(dispatch_get_main_queue(), ^{
                [HUD_code dismiss];
         });
});
4

3 に答える 3

5

UIKit クラスは、特に記載されている場合を除き、メイン スレッドからのみ使用できるように文書化されています。(たとえば、UIFontはスレッドセーフであると文書化されています。)

UIKit関数のスレッド セーフ(クラスとは異なります) に関する明示的な包括的声明はないため、一般的にスレッド セーフであると想定するのは安全ではありません。のような一部の UIKit 関数UIGraphicsBeginImageContextがスレッドセーフであると明示的に文書化されているという事実は、UIKit 関数が一般的にスレッドセーフではないことを意味します。

UIImageWriteToSavedPhotosAlbum非同期の完了メッセージを送信できるため、メイン スレッドでそれを呼び出し、その完了サポートを使用して[HUD_code dismiss].

于 2013-01-08T05:41:38.590 に答える
3

誰かが知りたい、またはコメントしたい(感謝している)場合は、回答を読んだ後の私の最新のコードを次に示します。

-(void)saveToLibrary {

            if (_imageView.image != NULL) {
                messageHUD = @"Saving Image...";
                [SVProgressHUD showWithStatus:messageHUD];
                UIImageWriteToSavedPhotosAlbum(_imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
            }
    }

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    UIAlertView *alert;

    // Unable to save the image
    if (error) {
        alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                           message:@"Unable to save image to Photo Album."
                                          delegate:self cancelButtonTitle:@"Ok"
                                 otherButtonTitles:nil];
    }else {// All is well
        messageHUD = @"Success!\nImage Saved.";
        [SVProgressHUD showSuccessWithStatus:messageHUD];
        [self myPerformBlock:^{[SVProgressHUD dismiss];} afterDelay:0.5];
    }
}

myPerformBlock は次のリンクからのものですhttps://gist.github.com/955123

于 2013-01-08T06:47:08.370 に答える
1

これはバックグラウンド スレッドで実行できると思いますが、間違っていますか?

正直なところ、これは UI の更新とはまったく関係がなく、単なるファイル操作であるため、私もそう思います。ただし、Apple のドキュメントには、UIKit へのすべての呼び出しはメイン スレッドで実行する必要があると記載されています(他の何かが明示的に記載されている場合を除く)。この関数も例外ではなく、メイン スレッドで呼び出す必要があります。

ちなみに、この関数自体は非同期です。画像が保存されるときに、2 番目と 3 番目の引数として提供されるコールバック オブジェクト/セレクターに通知するため、UI をブロックしません。

于 2013-01-08T05:40:10.880 に答える