6

値が変わる可能性のある単純なreadOnlyプロパティがある場合があります

@property (readonly) NSFetchedResultsController * FetchController;
@property (readonly) NSFetchRequest * FetchRequest;
@property (readonly) NSPredicate * KeywordPredicate;

値の変更は、ある種の単純なポインター操作によって、瞬く間に行われると思います。何かのようなもの

_FetchRequest = newFetchRequest;

実際の変更プロセスは大きく変わる可能性がありますが、実際の変更はその1行にある必要があります。

問題は、そのような単純なポインタ代入は常にアトミックなのかということです。その1行が実際に複数行のマシンコードで構成されていて、誰かがそれらのマシンコード間のプロパティを要求した場合はどうでしょうか。

最後に、問題は、ポインターの単純な代入演算子が常にアトミックであるかどうかです。

もしそうなら、それがアトミックであり、そうでない場合はどうなりますか?もちろん、単純な代入演算子は、複雑なオブジェクトに対してはアトミックではありません。

では、これらの単純な1行代入演算子は、どの程度アトミックなのでしょうか。ポインターとプリミティブ型の場合、常にそうなりますか?

4

2 に答える 2

5

読み取り専用操作を本質的にアトミックと見なすのはよくある誤解です。保証はありません。アトミック性がスレッドセーフを保証するというのもよくある誤解ですが、それは別の問題です。

読み取り専用プロパティのアトミックプロパティと非アトミックプロパティの違いはatomic、読み取り専用取得メソッドから返される値が整数であることを保証することです(これはデフォルトですが、宣言されていません)。

つまり、オブジェクトの場合、保持されて自動解放されます。構造体の場合、適切なロックを使用して、構造体の整数値が返されるようにします。

プロパティがパブリックに読み取り専用として宣言されているからといって、内部使用のために読み取り/書き込みとして再宣言されることを排除するものではないことに注意してください。したがって、アトミックと非アトミックの違いは非常に重要である可能性があります。クラスは、読み取り専用プロパティを非アトミックとして宣言する一方で、クラス上のすべてのAPIを1つのスレッドからのみ使用する必要があることを文書化する場合があります。

于 2012-10-19T07:13:47.697 に答える
4

この文脈でatomic(またはより適切には)が何を意味するのか誤解していると思います。nonatomic最も簡単な説明はobjc-accessors.mmそれ自体で見つけることができます:

id objc_getProperty_non_gc(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
    // Retain release world
    id *slot = (id*) ((char*)self + offset);
    if (!atomic) return *slot;

    // Atomic retain release world
    spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
    _spin_lock(slotlock);
    id value = objc_retain(*slot);
    _spin_unlock(slotlock);

    // for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.
    return objc_autoreleaseReturnValue(value);
}

ご覧のとおり、ここでのアトミック性とは、返されたオブジェクトの有効性のみを指します。それはあなたがそれを使用している間それが割り当て解除されないことを保証するためにそれを保持して自動解放しました。

これ[[obj retain] autorelease]が実行されなかった場合、別のスレッドがプロパティを設定する可能性があります。これにより、前のプロパティ(つまり、使用しているプロパティ)が解放され、割り当てが解除される可能性があります。

于 2012-10-19T04:39:01.240 に答える