プロパティ宣言でatomic
とnonatomic
はどういう意味ですか?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
これら3つの運用上の違いは何ですか?
最後の2つは同一です。 "atomic"がデフォルトの動作です(実際にはキーワードではありません。それは - 最近のバージョンのllvm/clangにキーワードとしてnonatomic
の欠如によってのみ指定されますatomic
が追加されました。
メソッドの実装を@synthesizingしていると仮定すると、アトミックと非アトミックは生成コードを変更します。あなたがあなた自身のセッター/ゲッターを書いているなら、アトミック/非アトミック/保持/代入/コピーは単なる諮問です。 (注:@synthesizeは、最近のバージョンのLLVMではデフォルトの動作になりました。インスタンス変数を宣言する必要もありません。自動的に合成され、偶然の直接アクセスを防ぐために_
が先頭に追加されます).
"atomic"の場合、他のスレッドでのセッターの動作に関係なく、合成されたセッター/ゲッターは、 whole 値が常にゲッターから返されるか、またはセッターによって設定されるようにします。つまり、スレッドBがセッターを呼び出している間にスレッドAがゲッターの真ん中にある場合、実際の有効な値(自動解放されたオブジェクト)がAの呼び出し元に返されます。
nonatomic
では、そのような保証はありません。したがって、nonatomic
は "atomic"よりかなり速いです。
"atomic"がnotをすることは、スレッドの安全性を保証することです。スレッドAがスレッドBとセッターを異なる値で呼び出すCと同時にゲッターを呼び出している場合、スレッドAは3つの値のいずれか、つまりセッターが呼び出される前、またはセッターに渡される値のいずれかを返します。同様に、オブジェクトはBまたはCの値で終わることがありますが、わかりません。
マルチスレッドプログラミングの主な課題の1つであるデータの完全性の確保は、他の方法でも達成できます。
これに追加:
単一のプロパティのatomicity
は、複数の依存プロパティが作用しているときにスレッドの安全性を保証することもできません。
検討してください:
@property(atomic, copy) NSString *firstName;
@property(atomic, copy) NSString *lastName;
@property(readonly, atomic, copy) NSString *fullName;
この場合、スレッドAはsetFirstName:
を呼び出してからsetLastName:
を呼び出すことによって、オブジェクトの名前を変更できます。その間、スレッドBはスレッドAの2つの呼び出しの間にfullName
を呼び出すことができ、古い姓と結合された新しい姓を受け取ります。
これに対処するには、 トランザクションモデル が必要です。すなわち依存プロパティが更新されている間にfullName
へのアクセスを排除することを可能にする他の種類の同期および/または除外。
これはAppleの ドキュメンテーション で説明されていますが、以下は実際に起こっていることのいくつかの例です。 "atomic"キーワードはありません。 "nonatomic"を指定しないとプロパティはアトミックになりますが、 "atomic"を明示的に指定するとエラーになります。
//@property(nonatomic, retain) UITextField *userName;
//Generates roughly
- (UITextField *) userName {
return userName;
}
- (void) setUserName:(UITextField *)userName_ {
[userName_ retain];
[userName release];
userName = userName_;
}
現在、アトミックな変種はもう少し複雑です。
//@property(retain) UITextField *userName;
//Generates roughly
- (UITextField *) userName {
UITextField *retval = nil;
@synchronized(self) {
retval = [[userName retain] autorelease];
}
return retval;
}
- (void) setUserName:(UITextField *)userName_ {
@synchronized(self) {
[userName_ retain];
[userName release];
userName = userName_;
}
}
基本的に、アトミック版はスレッドの安全性を保証するためにロックをかけなければならず、またオブジェクトに対する参照カウント(およびそれをバランスさせるための自動解放カウント)を増やしている。別のスレッドが値を設定しているために参照カウントが0になると、競合状態になる可能性があります。
プロパティがスカラー値なのかオブジェクトなのか、そして保持、コピー、読み取り専用、非原子的なものなどがどのように相互作用するかに応じて、これらのことがどのように機能するかについては、実際に多数の異なる変形があります。一般に、プロパティシンセサイザーは、すべての組み合わせに対して「正しいこと」を実行する方法を知っているだけです。
違いを理解するための最良の方法は、次の例を使用することです。
"name"というアトミック文字列プロパティがあり、スレッドAから[self setName:@"A"]
を呼び出し、スレッドBから[self setName:@"B"]
を呼び出し、スレッドCから[self name]
を呼び出すと、異なるスレッドに対するすべての操作が連続して実行されます。セッターまたはゲッターを実行すると、他のスレッドは待機します。
これにより、プロパティ "name"の読み書きが安全になりますが、別のスレッドDが同時に[name release]
を呼び出すと、setter/getter呼び出しが含まれないため、この操作でクラッシュが発生する可能性があります。これは、オブジェクトが読み取り/書き込みに対して安全(ATOMIC)であることを意味しますが、別のスレッドが同時に任意のタイプのメッセージをオブジェクトに送信できるため、スレッドに対して安全ではありません。開発者はそのようなオブジェクトに対してスレッドセーフを確保する必要があります。
プロパティ "name"がアトミックでなかった場合は、上記の例のすべてのスレッド(A、B、C、D)が同時に実行され、予期しない結果が生じます。アトミックの場合、A、B、Cのいずれかが先に実行されますが、Dはまだ並列実行できます。
構文とセマンティクスは、この質問に対する他の優れた回答によってすでに明確に定義されています。 executionおよびperformanceの詳細が十分でないため、回答を追加します。
これら3つの機能の違いは何ですか?
私は常にアトミックを非常に奇妙なデフォルトだと考えていました。抽象化レベルでは、クラスのアトミックプロパティをビークルとして使用して、100%スレッドセーフを実現することが重要です。真に正しいマルチスレッドプログラムの場合、プログラマーによる介入がほぼ確実に必要です。一方、パフォーマンス特性と実行の詳細はまだ詳しくありません。長年にわたっていくつかの非常にマルチスレッド化されたプログラムを書いてきたので、アトミックはどんな目的にも理にかなっていなかったので、私は常にnonatomic
としてプロパティを宣言していました。アトミックプロパティと非アトミックプロパティの詳細についての議論の際、 この質問 で、いくつかのプロファイリングで奇妙な結果に遭遇しました。
実行
OK。最初に明確にしたいのは、ロックの実装が実装定義および抽象化されていることです。 Louisは彼の例で@synchronized(self)
を使用しています。これはよくある混乱の原因と考えています。実装は実際には@synchronized(self)
;を使用しません。オブジェクトレベルスピンロックを使用します。 Louisのイラストは、私たちがよく知っている構造を使用した高レベルのイラストには適していますが、@synchronized(self)
を使用しないことを知っておくことが重要です。
別の違いは、アトミックプロパティがゲッター内でオブジェクトを保持/解放するということです。
パフォーマンス
興味深い部分があります:uncontested(たとえばシングルスレッド)の場合のアトミックプロパティアクセスを使用したパフォーマンスは、場合によっては非常に高速になります。理想的ではない場合、アトミックアクセスの使用は、nonatomic
のオーバーヘッドの20倍以上のコストがかかる可能性があります。 7スレッドを使用したContestedの場合は、3バイトの構造体では44倍遅くなりました(2.2 GHz Core i7 Quad-Core 、x86_64)。 3バイトの構造体は、非常に遅いプロパティの例です。
興味深い副注:3バイト構造体のユーザー定義のアクセサーは、合成されたアトミックアクセサーより52倍高速でした。または、合成された非原子アクセサーの速度の84%。
争われたケースのオブジェクトも50倍を超えることができます。
最適化の数と実装のバリエーションのため、これらのコンテキストでの実際の影響を測定することは非常に困難です。 「プロファイリングして問題がない限り、それを信頼してください」というような声がよく聞こえます。抽象化レベルのため、実際の影響を測定することは実際には非常に困難です。プロファイルから実際のコストを調べることは非常に時間がかかり、抽象化のために非常に不正確になる可能性があります。同様に、ARCとMRCは大きな違いを生むことができます。
それでは、ステップバックして、notプロパティアクセスの実装に焦点を当て、objc_msgSend
のような通常の容疑者を含め、実際の高レベルの結果を調べます。 uncontestedケース(秒単位の値)でのNSString
ゲッターの多くの呼び出しの場合:
おそらくご想像のとおり、参照カウントアクティビティ/サイクリングは、アトミックおよびARCの重要な貢献者です。また、争われたケースでは大きな違いが見られます。
パフォーマンスには細心の注意を払っていますが、私はまだSemantics First!と言います。一方、パフォーマンスは多くのプロジェクトにとって低い優先度です。ただし、使用するテクノロジの実行の詳細とコストを知っていても、確かに害はありません。ニーズ、目的、能力に合った適切なテクノロジーを使用する必要があります。うまくいけば、これにより数時間の比較が節約され、プログラムを設計する際に十分な情報に基づいた意思決定ができるようになります。
アトミック =スレッドセーフ
非原子 =スレッドセーフではない
インスタンス変数は、ランタイム環境によるそれらのスレッドの実行のスケジューリングやインターリーブに関係なく、また呼び出しコード側での追加の同期やその他の調整なしに、それらが複数のスレッドからアクセスされたとき正しく動作する場合、スレッドセーフです。
スレッドがインスタンスの値を変更すると、変更された値はすべてのスレッドで使用可能になり、一度に1つのスレッドだけが値を変更できます。
atomic
を使用する場所インスタンス変数がマルチスレッド環境でアクセスされる場合。
atomic
の意味:nonatomic
はランタイムからのウォッチドッグ作業を必要としないため、nonatomic
ほど速くはありません。
nonatomic
を使用する場所インスタンス変数が複数のスレッドによって変更されない場合は、それを使用できます。パフォーマンスが向上します。
アトミックおよび非アトミックプロパティについてのかなりよく説明された説明を見つけました ここ 。これは同じからいくつかの関連するテキストです:
'原子'はそれが分解できないことを意味します。 OS /プログラミングの用語では、アトミック関数呼び出しは割り込むことができないものです - 関数全体を実行し、それが完了するまでOSの通常のコンテキスト切り替えによってCPUからスワップアウトしないでください。念のために言っておきますが、CPUは一度に1つの操作しか実行できないため、OSはマルチタスクの錯覚を与えるために、CPUへのアクセスを実行中のすべてのプロセスに切り替えます。 。 CPUスケジューラは、実行中の任意の時点で(関数呼び出しの途中であっても)プロセスを中断することができます(そして中断します)。そのため、2つのプロセスが同時に変数を更新しようとする共有カウンタ変数の更新などのアクションでは、それらを「アトミックに」実行する必要があります。つまり、各更新アクションを他のプロセスに切り替える前に完全に終了する必要があります。 CPU。
だから私はこの場合アトミックリーダーメソッドが中断できないことを意味すると思います - 実際にはメソッドによって読み込まれている変数が途中で値を変更できないことを意味します。 CPUに交換しました。
atomic
変数は割り込むことができないので、いつでもそれらに含まれる値は unsorrupted であることが保証されます(ただし、このスレッドロックを確実にすることでそれらへのアクセスが遅くなります)。一方、non-atomic
変数はそのような保証はしませんが、アクセスが速くなるという贅沢を提供します。まとめると、変数が同時に複数のスレッドからアクセスされることがないことがわかっている場合は、non-atomic
を使用してください。
非常に多くの記事を読んだ後、Stack Overflowが投稿し、可変プロパティの属性をチェックするデモアプリケーションを作成した後、私はすべての属性情報をまとめることにしました。
atomic
//デフォルトnonatomic
strong = retain
//デフォルトweak = unsafe_unretained
retain
assign
//デフォルトunsafe_unretained
copy
readonly
readwrite
//デフォルト記事{ iOSの可変プロパティ属性または修飾子 では、上記のすべての属性を見つけることができます。これは間違いなく役に立ちます。
atomic
atomic
は、1つのスレッドだけが変数にアクセスすることを意味します(静的型)。atomic
はスレッドセーフです。atomic
がデフォルトの動作です例:
@property (retain) NSString *name;
@synthesize name;
nonatomic
nonatomic
は、マルチスレッドが変数にアクセスすることを意味します(動的型)。nonatomic
はスレッドセーフではありません。nonatomic
はデフォルトの動作ではありません。 property属性にnonatomic
キーワードを追加する必要があります。例:
@property (nonatomic, retain) NSString *name;
@synthesize name;
アトミックは、プロパティへのアクセスがアトミックな方法で実行されることを保証します。例えば。それは常に完全に初期化されたオブジェクトを返します。あるスレッドのプロパティのget/setは他のスレッドがそれにアクセスする前に完了しなければなりません。
次の関数が2つのスレッドで同時に発生していると想像すると、その結果が美しくない理由がわかります。
-(void) setName:(NSString*)string
{
if (name)
{
[name release];
// what happens if the second thread jumps in now !?
// name may be deleted, but our 'name' variable is still set!
name = nil;
}
...
}
長所: 毎回完全に初期化されたオブジェクトを返すことで、マルチスレッドの場合に最適な選択肢となります。
短所: パフォーマンスが低下し、実行が少し遅くなります
Atomicとは異なり、完全に初期化されたオブジェクトが毎回返されることを保証するものではありません。
長所: 非常に速い実行です。
短所: マルチスレッドの場合のゴミ値の可能性。
最も簡単な回答最初:2番目の2つの例の間に違いはありません。デフォルトでは、プロパティアクセサはアトミックです。
ガベージコレクションされていない環境(つまり、保持/解放/自動解放を使用している場合)のアトミックアクセサは、別のスレッドが値の正しい設定/取得を妨げないようにロックを使用します。
マルチスレッドアプリケーションを作成するときの詳細情報およびその他の考慮事項については、AppleのObjective-C 2.0ドキュメントの「 パフォーマンスとスレッド化 」のセクションを参照してください。
アトミックは、1つのスレッドだけが変数にアクセスすることを意味します(静的型)。アトミックはスレッドセーフですが、遅いです。
非アトミックとは、複数のスレッドが変数にアクセスすることを意味します(動的型)。ノンアトミックはスレッドセーフではありませんが、高速です。
アトミックは スレッドセーフ 、それは 低速 そしてそれは 十分に保証(保証されていない) ロックされた値だけが同じゾーン上でアクセスを試みている数に関係なく提供されるアトミックを使用するとき、この関数の内部に書かれたコードの一部はクリティカルセクションの一部になり、一度に1つのスレッドしか実行できません。
それはスレッドの安全性を保証するだけです。それを保証するものではありません。 私が言っているのはあなたがあなたの車のために専門の運転手を雇うということです、それでもまだそれは車が事故に遭遇しないことを保証するものではありません。ただし、確率はわずかなままです。
アトミック - 分解できないので、結果は期待通りです。非アトミックの場合 - 別のスレッドがメモリゾーンにアクセスすると、それを変更できます。そのため、結果は予想外です。
コードトーク:
アトミックにプロパティのゲッターとセッターを安全にします。例えば、uが書いたとします。
self.myProperty = value;
スレッドセーフです。
[myArray addObject:@"Abc"]
スレッドセーフではありません。
そのようなキーワード「アトミック」はありません
@property(atomic, retain) UITextField *userName;
上記のように使用できます
@property(retain) UITextField *userName;
Stack Overflowの質問@ property(atomic、retain)NSString * myStringを使用すると問題が発生しますを参照してください。
default はatomic
です。つまり、このプロパティを使用すると必ずパフォーマンスが低下しますが、スレッドセーフです。 Objective-Cが行うことは、ロックを設定することです。そのため、setter/getterが実行される限り、実際のスレッドだけが変数にアクセスできます。
Ivar _internalを持つプロパティのMRCを使った例:
[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
最後の2つは同じです。
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName; // defaults to atomic
一方、nonatomic
はコードに何も追加しません。そのため、セキュリティメカニズムを自分でコーディングした場合、スレッドセーフになります。
@property(nonatomic, retain) UITextField *userName;
キーワードを最初のプロパティ属性として記述する必要はまったくありません。
忘れないでください、これはプロパティ全体がスレッドセーフであるという意味ではありません。 setter/getterのメソッド呼び出しのみです。しかし、2つの異なるスレッドで同時にセッターとその後にゲッターを使用すると、それも壊れる可能性があります。
アトミック(デフォルト)
アトミックがデフォルトです。何も入力しなければ、プロパティはアトミックです。アトミックプロパティは、あなたがから読み出そうとした場合、あなたが有効な値を取り戻すことが保証されています。それはその値が何であるかについていかなる保証もしませんが、あなたは良いデータを取り戻すでしょう、単にジャンクメモリではありません。これができるのは、1つの変数が1つの変数を指す複数のスレッドまたは複数のプロセス、あるいは1つのスレッドが指すことができる複数のプロセスがある場合です。それらが同時にヒットした場合、リーダースレッドは2つの値のどちらかを取得することが保証されます。変更前または変更後のいずれか。原子があなたに与えないのは、あなたがこれらの値のうちどれをあなたが得ることができるかについてのある種の保証である。 Atomicは、スレッドセーフであることと実際にはよく混同されています、それは正しくありません。スレッドの安全性を他の方法で保証する必要があります。しかし、atomicは、読み込もうとするとあなたが何らかの価値を取り戻すことを保証します。
非原子
逆に言えば、非原子的とは、ご想像のとおり、「その原子的なことをしないこと」を意味します。失ったのは、あなたが常に何かを取り戻すという保証です。 。 書き込みの途中で読み込もうとすると、ゴミデータが戻ってくる可能性があります。しかし、その一方で、あなたはもう少し速く行きます。アトミックプロパティは確実に値を取り戻すことができるようにするために何らかの魔法をかける必要があるため、少し遅くなります。 それがあなたがたくさんアクセスしているプロパティであるなら、あなたはあなたがそのスピードペナルティを被っていないことを確かめるためにをnonatomicに落としたくなるかもしれません。
ここにもっと見てください: https://realm.io/news/tmi-objective-c-property-attributes/ /
始める前に:新しいライターを実行するには、メモリー内のすべてのオブジェクトをメモリーから解放する必要があることを知っておく必要があります。紙に書くように、何かの上に単に書くことはできません。あなたはmust最初にそれを消去(dealloc)し、それから書き込むことができます。消去が完了(または半分完了)し、まだ何もまだ書き込まれていない(または半分書き込まれている)場合、それを読み取ろうとすると非常に問題がある!アトミックおよび非アトミックは、この問題をさまざまな方法で処理するのに役立ちます。
最初に this を読み、次に Bbumの答え を読みます。さらに、私の要約を読んでください。
atomic
は常に保証します
保持カウントは、Objective-Cでメモリを管理する方法です。オブジェクトを作成すると、保持カウントは1になります。オブジェクトに保持メッセージを送信すると、保持カウントは1ずつ増加します。オブジェクトに解放メッセージを送信すると、保持カウントは1ずつ減少します。オブジェクトにautoreleaseメッセージを送信すると、その保持カウントは将来のある段階で1ずつ減少します。オブジェクトの保持カウントが0に減少すると、割り当てが解除されます。
何?!マルチスレッドと スレッドセーフティ は異なりますか?
はい。マルチスレッドとは、複数のスレッドが共有データを同時に読み取ることができ、クラッシュしないことを意味しますが、自動解放されていない値から読み取らないことを保証しません。スレッドセーフを使用すると、読んだものが自動リリースされないことが保証されます。デフォルトですべてをアトミックにしないのは、パフォーマンスコストがあり、ほとんどの場合、スレッドセーフが本当に必要ないからです。私たちのコードのいくつかの部分はそれを必要とし、それらのいくつかの部分のために、ロック、ミューテックスまたは同期を使用してスレッドセーフな方法でコードを書く必要があります。
nonatomic
全体として、2つの側面が異なります。
自動解放プールの有無によってクラッシュするかどうか。
「まだ終了していない書き込みまたは空の値」の途中で読み取りを許可するか、値が完全に書き込まれた場合のみ読み取りを許可および許可しない。
プロパティをマルチスレッドコードで使用している場合は、非原子属性と原子属性の違いを確認できます。ノンアトミックはアトミックより速く、アトミックはスレッドセーフであり、ノンアトミックではありません。
Vijayendra Tripathiはすでにマルチスレッド環境の例を挙げています。
宣言する方法:
アトミックがデフォルトなので、
@property (retain) NSString *name;
実装ファイル内のAND
self.name = @"sourov";
3つのプロパティに関連するタスクが
@property (retain) NSString *name;
@property (retain) NSString *A;
@property (retain) NSString *B;
self.name = @"sourov";
すべてのプロパティは並列に機能します(非同期の場合と同様)。
スレッドから "name"を呼び出すと、 _ a _ 、
そして
あなたが呼び出す場合は同時に
[self setName:@"Datta"]
fromスレッド _ b _ 、
Now * nameプロパティが非アトミックの場合 then
なぜアトミックではないスレッドが安全でないスレッドと呼ばれるのか、しかし、並列実行のためパフォーマンスは速いです
Now * nameプロパティがアトミックの場合
原子がスレッドセーフと呼ばれる理由and それが読み書きセーフと呼ばれる理由
このような状況での操作は連続して実行されます。 そしてパフォーマンスが低下します
- 非アトミックは、マルチスレッドが変数にアクセスすることを意味します(動的型)。
- ノンアトミックはスレッドセーフではありません。
- しかしパフォーマンスは速いです
-Nonatomicはデフォルトの動作ではありません。プロパティ属性にnonatomicキーワードを追加する必要があります。
In Swift SwiftプロパティがObjCの意味でノンアトミックであることを確認します。 1つの理由は、プロパティごとのアトミック性がニーズに十分かどうかを考えることです。
参照: https://forums.developer.Apple.com/thread/25642
さらに詳しい情報はウェブサイトをご覧ください http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
@propertyの属性について説明する前に、@ propertyの使用方法を知っておく必要があります。 @ propertyは、クラスがカプセル化することを目的とした情報を定義する方法を提供します。 @propertyを使用してオブジェクト/変数を宣言すると、そのオブジェクト/変数はそのクラスをインポートする他のクラスからアクセス可能になります。ヘッダーファイルで@propertyを使用してオブジェクトを宣言する場合、それを合成する必要があります。実装ファイルで@synthesizeを使用します。
例:
.hクラス
@interface ExampleClass : NSObject
@property (nonatomic, retain) NSString *name;
@end
.mクラス
@implementation ExampleClass
@synthesize name;
@end
これでコンパイラはnameのアクセサメソッドを合成します。
ExampleClass *newObject=[[ExampleClass alloc]init];
NSString *name1=[newObject name]; // get 'name'
[obj setName:@“Tiger”];
@propertyの属性のリスト:アトミックノナトミック[]保持[]読み取り専用読み取り専用読み取り専用割り当てる。
atomic:これはデフォルトの動作です。オブジェクトがアトミックとして宣言されている場合、それはスレッドセーフになります。スレッドセーフとは、そのクラスの特定のインスタンスの1つのスレッドしかそのオブジェクトを制御できないことを意味します。
例:
@property NSString *name; //by default atomic
@property (atomic)NSString *name; // explicitly declared atomic
nonatomic:スレッドセーフではありません。 nonatomic property属性を使用して、合成されたアクセサが単に値を直接設定または返すように指定できます。同じ値が異なるスレッドから同時にアクセスされるとどうなるかについては保証されません。このため、アトミックプロパティよりもノンアトミックプロパティにアクセスする方が速いです。 @property (nonatomic)NSString *name;
set:メソッドはオブジェクトの保持数を増やすので、自動解放プールのメモリを占有します。 @property (retain)NSString *name;
コピー:あなたがコピーを使用する場合、あなたは保持を使用することはできません。クラスのコピーインスタンスを使用すると、独自のコピーが含まれます。可変文字列が設定され、その後変更された場合でも、インスタンスは設定された時点の値をすべて取得します。セッターおよびゲッターメソッドは合成されません。
@property (copy) NSString *name;
NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];
xyzObj.name = nameString;
[nameString appendString:@"Pizza"];
readonly:プロパティをsetterメソッドで変更したくない場合は、readonlyでプロパティを宣言することができます。 @property (readonly) NSString *name;
readwrite:がデフォルトの動作です。 readwrite属性を明示的に指定する必要はありません。
@property (readwrite) NSString *name;
assign:値をコピーまたは保持するのではなく、インスタンス変数に直接代入するセッターを生成します。これは、NSIntegerやCGFloatのようなプリミティブ型、あるいはデリゲートのように直接所有していないオブジェクトに最適です。
@property (assign) NSInteger year;
強い:保持の代わりになります。 @property (nonatomic, strong) AVPlayer *player;
unsafe_unretained:CocoaとCocoa Touchにはまだ弱い参照をサポートしていないクラスがいくつかあります。つまり、弱いプロパティや弱いローカル変数を宣言して追跡することはできません。これらのクラスには、NSTextView、NSFont、NSColorSpaceなどがあります。これらのクラスのいずれかへの弱い参照を使用する必要がある場合は、安全でない参照を使用する必要があります。安全でない参照は、関連オブジェクトを維持しないという点で弱い参照に似ていますが、勝ちます宛先オブジェクトの割り当てが解除されている場合は、nilに設定しないでください。
@property (unsafe_unretained) NSObject *unsafeProperty;
アトミックプロパティは、それに対してgetter&setterを実行しているスレッドの数に関係なく、完全に初期化された値を確実に保持します。
Nonatomicプロパティは、合成アクセッサが単に値を直接設定または返すことを指定します。同じ値が異なるスレッドから同時にアクセスされるとどうなるかについては保証されません。
Atomicとは、一度に1つのスレッドだけが変数にアクセスできることを意味します(静的型)。アトミックはスレッドセーフですが、遅いです。
ノンアトミックとは、複数のスレッドが同時に変数にアクセスできることを意味します(動的型)。ノンアトミックはスレッドセーフではありませんが、高速です。
アトミックを使用している場合は、スレッドが安全で読み取り専用になることを意味します。ノンアトミックを使用している場合は、複数のスレッドが変数にアクセスしてスレッドセーフではないことを意味しますが、高速に実行され、読み取りおよび書き込み操作が行われます。これは動的型です。
アトミックプロパティ : - アトミックプロパティが割り当てられた変数が1つのスレッドアクセスしか持たず、スレッドセーフであり、パフォーマンスの観点からも良い場合、デフォルトの動作になります。
非アトミックプロパティ : - アトミックプロパティが割り当てられた変数がマルチスレッドアクセスを持ち、スレッドセーフではなく、パフォーマンスの観点からも遅くなる場合、デフォルトの動作と2つの異なるスレッドがアクセスする場合同時に可変であると、予期しない結果が生じます。
原子性 atomic(デフォルト)
アトミックがデフォルトです。何も入力しなければ、プロパティはアトミックです。アトミックプロパティは、読み込もうとしたときに有効な値が返されることが保証されています。それはその値が何であるかについていかなる保証もしません、しかしあなたはただのジャンクメモリではなく、良いデータを取り戻すでしょう。これを可能にするのは、単一の変数を指す複数のスレッドまたは複数のプロセスがある場合、1つのスレッドが読み取り、もう1つのスレッドが書き込むことができる場合です。それらが同時にヒットした場合、リーダースレッドは2つの値のうちどちらかを取得することが保証されます。変更前または変更後のいずれかです。アトミックがあなたに与えないのは、あなたが得るかもしれないそれらの値のうちのものについてのある種の保証である。アトミックはスレッドセーフであることと本当によく混同されていますが、それは正しくありません。スレッドの安全性を他の方法で保証する必要があります。しかし、atomicは、読み込もうとしたときに何らかの価値を取り戻すことを保証します。
非原子
反対に、ノンアトミックとは、ご想像のとおり、「あのアトミックなことをしないでください」ということを意味します。失うことは、常に何かを取り戻すことを保証することです。書き込みの途中で読み込もうとすると、不要なデータが取り戻される可能性があります。しかし、その一方で、あなたは少し速く行きます。アトミックプロパティは、確実に値を取り戻すことができるようにするためにいくらか魔法をかける必要があるため、少し遅くなります。それがあなたが頻繁にアクセスしているという特性であるならば、あなたはあなたがそのスピードペナルティを被っていないことを確認するためにノンアトミックに落ちることを望むかもしれません。
礼儀 https://academy.realm.io/posts/tmi-objective-c-property-attributes/
Atomicityプロパティ属性(atomicおよびnonatomic)は、対応するSwiftプロパティ宣言には反映されませんが、Objective-C実装の原子性保証は、Swiftからインポートされたプロパティにアクセスしても有効です。
So - Objective-Cでアトミックプロパティを定義した場合、Swiftで使用してもアトミックプロパティは維持されます。
礼儀 https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c
全体の混乱を簡単にするために、ミューテックスロックを理解しましょう。
ミューテックスロックは、その名の通り、オブジェクトの可変性をロックします。そのため、そのオブジェクトがクラスによってアクセスされている場合、他のクラスは同じオブジェクトにアクセスできません。
IOSでは、@sychronise
はミューテックスロックも提供します。今度はFIFOモードで機能し、同じインスタンスを共有する2つのクラスの影響を受けないようにします。ただし、タスクがメインスレッドにある場合は、UIを保持してパフォーマンスを低下させる可能性があるため、アトミックプロパティを使用してオブジェクトにアクセスしないでください。
Atomic:NSLOCKを使用してスレッドをロックしてスレッドの安全性を確保します。
非アトミック:スレッドロックメカニズムがないため、スレッドセーフを保証しません。
真実は、彼らがアトミックプロパティを実装するためにスピンロックを使うということです。以下のようなコード:
static inline void reallySetProperty(id self, SEL _cmd, id newValue,
ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
id oldValue;
id *slot = (id*) ((char*)self + offset);
if (copy) {
newValue = [newValue copyWithZone:NULL];
} else if (mutableCopy) {
newValue = [newValue mutableCopyWithZone:NULL];
} else {
if (*slot == newValue) return;
newValue = objc_retain(newValue);
}
if (!atomic) {
oldValue = *slot;
*slot = newValue;
} else {
spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
_spin_lock(slotlock);
oldValue = *slot;
*slot = newValue;
_spin_unlock(slotlock);
}
objc_release(oldValue);
}