AppleがUIKitをメインスレッドでのみ使用することを公式に推奨していることを私は知っています。ただし、iOS 4.0以降、UIImageはスレッドセーフであるという主張も耳にしました。この主張を裏付ける文書が見つかりません。
この主張を裏付ける情報はありますか?データの保存と画像データのデコードに使用されるクラスとして、UIImageは、適切に設計されていればスレッドセーフである必要があります。
AppleがUIKitをメインスレッドでのみ使用することを公式に推奨していることを私は知っています。ただし、iOS 4.0以降、UIImageはスレッドセーフであるという主張も耳にしました。この主張を裏付ける文書が見つかりません。
この主張を裏付ける情報はありますか?データの保存と画像データのデコードに使用されるクラスとして、UIImageは、適切に設計されていればスレッドセーフである必要があります。
イメージオブジェクトは不変であるため、作成後にプロパティを変更することはできません。これは、通常、初期化時に画像のプロパティを指定するか、画像のメタデータに依存してプロパティ値を提供することを意味します。また、画像オブジェクト自体がどのスレッドからでも安全に使用できることを意味します。既存の画像オブジェクトのプロパティを変更する方法は、利用可能な便利な方法の1つを使用して、必要なカスタム値を使用して画像のコピーを作成することです。
(エンファシスマイン)
したがって、少なくとも2014年5月13日現在のSDKの現在のバージョンでは、「画像オブジェクト自体はどのスレッドからでも安全に使用できます」。
AppleがメインスレッドでUIKItの要素を使用することを推奨しているのは事実です。
注:ほとんどの場合、UIKitクラスはアプリケーションのメインスレッドからのみ使用する必要があります。これは、UIResponderから派生したクラス、またはアプリケーションのユーザーインターフェイスの操作を伴うクラスに特に当てはまります。
UIImageはUIResponderから派生したものではないため、実際にはインターフェイス/画面に表示されません。次に、別のスレッドでUIImagesを使用して操作を行うのは安全です。
ただし、これは私の経験に基づいており、公式のドキュメントは見ていません。
ここに以前の回答が投稿されて以来、Appleはドキュメントを更新したようです。最新のドキュメントによると、任意のスレッドからUIImageインスタンスを作成して使用するのが安全です。
イメージオブジェクトは不変であるため、作成後にプロパティを変更することはできません。ほとんどの画像プロパティは、付随する画像ファイルまたは画像データのメタデータを使用して自動的に設定されます。画像オブジェクトの不変の性質は、どのスレッドからでも安全に作成および使用できることも意味します。
iOSの新機能:iOS 4.0リリースノートでは、UIKitフレームワークの機能強化に次のビットが含まれています。
UIKitでのグラフィックスコンテキストへの描画がスレッドセーフになりました。具体的には、グラフィックスコンテキストへのアクセスと操作に使用されるルーチンが、さまざまなスレッドに存在するコンテキストを正しく処理できるようになりました。文字列と画像の描画がスレッドセーフになりました。複数のスレッドでカラーオブジェクトとフォントオブジェクトを安全に使用できるようになりました。
したがって、UIImageはiOS4.0以降でスレッドセーフです。
簡単に言うと、UIImageはスレッドセーフではないか、デバッグ後に現在経験しているように、メインスレッドでのみ機能します。
それがお役に立てば幸いです。私はこれについてAppleからもっと明確にしたい、あるいは別のスレッドでレンダリングできるUIImageクラスをもっと良くしたい。難しいことではないはずです...
編集:いくつかの調査の後、私はそれが「UIGraphicsGetImageFromCurrentImageContext();」であることがわかりました。それがトラブルの原因になります。トピックから少し外れていますが、おそらくこれは役に立ちます: https ://coderwall.com/p/9j5dca
ZacharyWaldowskiに感謝します。
スレッドセーフは問題ではありません。どのスレッドも同時に(同時に)コンテキストにアクセスしようとする可能性があります。そして、それは一般的には問題ありませんが、iOSデバイスの写真編集拡張機能のようにメモリが少ない状況では、1つのコンテキストにアクセスする2つのスレッドがメモリ不足のためにアプリをクラッシュさせる可能性があります。
これは、CoreImageフィルターをvImage操作と混合するときに発生します。どちらもスレッドセーフですが、ARCはCore Imageオブジェクトを処理する前にvImageバッファデータを解放しないため、ある時点でメモリに画像の2つのコピーがあります。
したがって、スレッドと並行性を理解せずにスレッドセーフの知識が完全であると考えることは決してありません。これは、スレッドセーフに関する質問への回答の2倍になります。要するに、適切な質問は、画像処理について話しているときはいつでも、スレッドセーフがメモリ使用量にどのように適用されるかということです。
ここでタイヤを蹴っているだけの場合は、実際の問題が発生するまで質問をするのを待つ必要があります。ただし、次の移動を計画している場合は、画像処理コマンドを順番に実行する方法と、手動で割り当てを解除する方法を知っておく必要があります。メモリ内で処理されている画像のコピーが1つだけになるようにアプリを設計する必要があります。スレッドセーフであるかどうかにかかわらず、自動割り当て解除に依存してその呼び出しを行うことは絶対にしないでください。うまくいかないだろう。