4

このような呼び出しはスレッドセーフと見なされますか? UIImageを作成するだけで、UIの更新はありません。これに関するドキュメントが見つかりません。

UIImage * hiResImage = [[UIImage alloc] initWithContentsOfFile:path]; 

参考までに、後でこのようにメインスレッドでUIの更新を行います...

[imageViewForZoom performSelectorOnMainThread:@selector(setImage:) withObject:hiResImage waitUntilDone:NO];

私がすでに知っていること:

  • iOS4以降、UIKitの多くの描画メソッドがスレッドセーフになりました。ここから読んでください。
  • バックグラウンド スレッドで UI を更新しないでください (例: no [myImageView setImage:image];)

編集: 別の観点から見てみましょう。「スレッドセーフではない」とは、永久にブロックされる可能性があることを意味しますか? または、開始/期間の実行時間に保証がないことを意味します。後者の場合、画像のロード時に「不確定な量」の遅延が発生しても問題ありません。UI の更新はメイン スレッドで行われます。そのため、少なくとも UIImage を作成するためには、スレッドセーフでなくても問題ないと見なされます。

これは質問とはあまり関係がないことはわかっていますが、元の質問に対する明確な答えがないのではないかと心配しているので、指摘したいだけです:)

4

3 に答える 3

4

以下の私の経験は直接ではありませんUIImage initContentsFromFile:UIImage imageWithData、あなたの質問は UIImage スレッドの安全性に関するものです。

最近、いくつかのバックグラウンド スレッドを使用して画像をダウンロードする関数から[UIImage imageWithData:]呼び出される問題をデバッグする必要がありました。ダウンロードした画像は UI の更新に使用されるため、以下を使用する必要がありました。NSURLConnetionDelegateconnectionDidFinishLoading[NSOperationQueue mainQueue] addOperationWithBlock ...

- (void) connection:(URLConnection*)connection didReceiveData:(NSData *) data {
    [imgData appendData:data];
}

- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
    [NSOperationQueue mainQueue] addOperationWithBlock:^{
        UIImage *img = [UIImage imageWithData:imgData];
        // more code here to update the UI
    }];
}
  • iOS 7.x シミュレーターで実行する場合img、有効なイメージを保持します
  • iOS 7.x デバイス (iPod Touch) で実行する場合、img常にnil

デバッグ セッション中に、デバッガーが各ステートメントを一度に 1 行ずつステップ実行すると、問題が (一時的に) 消えたことに気付きました。UIImage私の理論では、デバッガーのステップモードで実行しても、実行中の同時スレッドを処理すること はできませんimageWithData。したがって、UIImage imageWithData(おそらく他の同様の関数も) スレッドセーフではないと思います。

@synchronizedブロックを使用すると問題が解決するようです

- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
    [NSOperationQueue mainQueue] addOperationWithBlock:^{
        @synchronized(imgData) {
            // Run the following in a synchronized block
            UIImage *img = [UIImage imageWithData:imgData];
        }
        // more code here ....
    }];
}
于 2013-10-20T02:29:27.187 に答える
2

Apple によると、答えはイエスです。任意のスレッドから UIImage を作成しても安全です。

画像オブジェクトは不変であるため、作成後にプロパティを変更することはできません。ほとんどの画像プロパティは、付随する画像ファイルまたは画像データのメタデータを使用して自動的に設定されます。画像オブジェクトの不変の性質は、どのスレッドからでも安全に作成および使用できることも意味します。

https://developer.apple.com/reference/uikit/uiimage

于 2017-03-21T06:26:21.477 に答える
1

はい。主にリモートファイルの場合、または多くの画像が読み込まれている場合、画像をバックグラウンドで読み込むことはかなり一般的な方法です。はい、メイン スレッドの UI のみを更新します。

編集:

いくつかの啓発的なコメントがあるため、「はい」という最初の回答を「経験と、イメージのロードに関して UIImage のスレッド セーフの実行可能な代替手段ではないという私の評価に基づいて、合理的だと思います。だと仮定します。ただし、各人には独自の意見が保証されており、おそらく、ここでのコード障害に関連するリスクが高すぎて、いかなる状況下でも仮定を立てることはできません.」

于 2012-10-07T06:15:13.903 に答える