1

同じプロパティ セットにアクセスする 2 つのスレッドがありますが、1 つはプロパティからの読み取りのみ、もう 1 つはプロパティへの書き込みのみです。

次のプロパティのうち、読み取り操作で同期する必要があるのはどれですか?また、書き込み操作で同期する必要があるのはどれですか?

@property (nonatomic) int myInt;
@property (nonatomic) NSInteger myInteger;
@property (nonatomic) CGImageRef cgImage;
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) NSMutableArray *array;
@property (nonatomic, strong) UIViewController *controller;

私の最初の本能は、すべての読み取りおよび書き込み操作を常に同期する必要があるということです。ただし、常に 1 つのスレッドが書き込みを行っており、1 つのスレッドが常に読み取りを行っているため、自分自身に自信がありません。確かに、確信が持てないので、常に同期することは「安全」ですが、実際には何が正しいのでしょうか?

何らかの理由で、myInt と myInteger は値渡しであるため、読み取りと書き込みのために同期する必要がないのではないかと感じています....?

4

1 に答える 1

4

まあ、これはアトミック プロパティが得意とするところです。それらがすべてアトミックである場合、部分的に書き込まれた結果を取得せずに読み書きできます。

ただし、並列プログラムで本当に役立つアトミック objc プロパティを見つけたことはありません。私は常に通常のロック、不変性などをもたらします。

アトミックを使用することはできますが、実際のケースではあまり効果がありません。それらは、実行コストでプログラムをよりスレッド耐性のある(安全ではない)ものにします(どちらも悪いです、ところで)。

ところで、ここでは値渡しは実際には問題ではありません。

変更可能な値またはオブジェクトを変更すること (たとえば、2 つのスレッドからその NSMutableArray を読み書きすること) と、相互に依存する ivar の整合性を維持することが主な問題です。

互いに依存している 2 つの ivar の整合性を維持する例:

int 型 (日、月) の 2 つのアトミック プロパティがあり、それらにアクセサーがあるとします。読み取りと書き込みが別々のスレッドから行われている場合、無効な日付 (2 月 31 日など) を読み取らないようにするためには、アトミック以上のものが必要になります。オブジェクトが部分的な更新の途中にないことを確実にする唯一の方法は、同期プリミティブまたは不変データを使用することです。これは、基本的なアトミック プロパティからあなたを救うことはできません。

簡単な答えは「アトミック」ですが、並行コンテキストのオブジェクトが非常に単純であるため、アトミックの中間点が真にスレッドセーフであることはめったにありません。

于 2012-08-10T18:01:40.727 に答える