nonatomicとatomicの違い

4158 ワード

ここにはObjective-C Property Attributesとstackoverflowを読むことができるblogがあります。ここでは簡単に説明します。


1、atomicおよびnonatomicは、コンパイラが生成したgetterおよびsetterが原子操作であるかどうかを決定するために使用される。


2.atomic:システムが生成したgetter/setterは、get、set操作の完全性を保証し、他のスレッドの影響を受けない。getterは、データの完全性を保証する完全なオブジェクトを得ることができますが、このオブジェクトはマルチスレッドの場合は確定できません。例:

@property(atomic,strong)NSMutableArray *arr;

スレッドループの読み取りデータ、スレッドループの書き込みデータの場合、setter、getterとは関係ないため、メモリの問題が発生するに違いありません.[self.arr objectAtIndex:index]を使用すると、スレッドは安全ではありません.良い解決策はロックをかけることです.

ここには誤りがあり、atomicがスレッドの安全を保証できると考えている人が多い。この言い方は実は正確ではない。私のブログ(Objective-C Property Attributes)には、次のような説明があります。

atomic (default)
Atomic is the default: if you don’t type anything, your property is atomic. An atomic property is guaranteed that if you try to read from it, you will get back a valid value. It does not make any guarantees about what that value might be, but you will get back good data, not just junk memory. What this allows you to do is if you have multiple threads or multiple processes pointing at a single variable, one thread can read and another thread can write. If they hit at the same time, the reader thread is guaranteed to get one of the two values: either before the change or after the change. What atomic does not give you is any sort of guarantee about which of those values you might get. Atomic is really commonly confused with being thread-safe, and that is not correct. You need to guarantee your thread safety other ways. However, atomic will guarantee that if you try to read, you get back some kind of value.

nonatomic
On the flip side, non-atomic, as you can probably guess, just means, “don’t do that atomic stuff.” What you lose is that guarantee that you always get back something. If you try to read in the middle of a write, you could get back garbage data. But, on the other hand, you go a little bit faster. Because atomic properties have to do some magic to guarantee that you will get back a value, they are a bit slower. If it is a property that you are accessing a lot, you may want to drop down to nonatomic to make sure that you are not incurring that speed penalty.


説明:Atomic is really commonly confused with being thread-safe,and that is not correct.You need to guarantee your thread safety other ways.すなわちatomicはオブジェクトマルチスレッドの安全を保証できない.したがってatomicはオブジェクトマルチスレッドの安全を保証できない.それはあなたが訪問したときに完璧なValueを返すことを保証できるだけです。アップルのドキュメントによると、原子性はスレッドの安全を保証することはできない。ただ原子性keywordを用いる属性に対してスレッドは安全である.クラスにとって必ずしもそうではない.例を挙げます。


スレッドAがgetterを調整し、同時にスレッドB、スレッドCがsetterを調整した場合、最後のスレッドAがgetした値は、B、C set以前の元の値、B setの値、C setの値の3つの可能性があります.また,最終的にこの属性の値は,B setの値であるか,C setの値であるかのいずれかである.したがってatomicは、オブジェクトのスレッドの安全を保証するものではありません.

3、nonatomic:データの完全性を保証しないで、nonatomicはあなたのオブジェクトを返して完全なvalueではないかもしれません。したがって,マルチスレッド環境では原子操作が必要であり,そうでなければ誤った結果を引き起こす可能性がある.しかし、atomicを使用するだけではオブジェクトスレッドは安全ではありません。また、オブジェクトスレッドにlockを追加してスレッドの安全を確保します。


4、nonatomicの速度はatomicより速い。ここでiOSでnonatomicを使用する理由を説明します。一般的にiOSプログラムのすべてのプロパティはnonatomicとして宣言されます。その理由は次のとおりです。


iOSで同期ロックを使用するコストが高いため、パフォーマンスに問題があります.一般的には、プロパティが「原子」である必要はありません.これは「スレッドセキュリティ」(thread safety)を保証するものではありません.「スレッドセキュリティ」の操作を実現するには、より深いロックメカニズムを採用しなければなりません.したがって、iOSプログラムではnonatomicプロパティが一般的に使用されます.しかし、Mac OS Xプログラムでは、atomicプロパティを使用してもパフォーマンスのボトルネックは通常ありません.

5、atomicとnonatomicの本質的な違い実はsetter方法での操作が異なる


nonatomicオブジェクトsetterとgetterメソッドの実装:
- (void)setCurrentImage:(UIImage *)currentImage
{
    if (_currentImage != currentImage) {
        [_currentImage release];
        _currentImage = [currentImage retain];
        
    }
}
- (UIImage *)currentImage
{
    return _currentImage;
}

atomicオブジェクトsetterメソッドとgetterメソッドの実装:
- (void)setCurrentImage:(UIImage *)currentImage
{
    @synchronized(self) {
        if (_currentImage != currentImage) {
            [_currentImage release];
            _currentImage = [currentImage retain];
            
        }
    }
}

- (UIImage *)currentImage
{
    @synchronized(self) {
        return _currentImage;
    }
}