アトミック属性と非アトミック属性の違いは何ですか?
-
09-09-2019 - |
質問
何をするか atomic
そして nonatomic
プロパティ宣言でという意味ですか?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
これら 3 つの操作上の違いは何ですか?
解決
最後の二つは同じです。 「アトミック」(それは実際にはキーワードではありません。なお、<ストライキ>;それが唯一nonatomic
スト>の不在によって指定された - atomic
はLLVM /打ち鳴らすの最近のバージョンでキーワードとして追加されました)デフォルトの動作です。
あなたは、原子対非原子の変更生成されたコードメソッドの実装を@synthesizingされていると仮定すると。あなたがあなた自身のセッター/ゲッターを書いている場合は、非アトミック/原子/割り当て/保持/コピー単なる助言しています。 (注意:@synthesizeは今、LLVMの最近のバージョンではデフォルトの動作であるインスタンス変数を宣言する必要もありません。彼らはあまりにも、自動的に合成され、不慮の直接アクセスを防止するために、自分の名前の前に付加_
を持つことになります。)。
を合成セッター/ゲッター、「アトミック」での全体の値は関係なく、常に他のスレッド上のセッターの活動の、ゲッターから返されるか、設定手段によって設定されていることが保証されます。自動解放オブジェクト、最も可能性が高い - - スレッドBは、セッター、実際の実行可能な値を呼び出している間、スレッドAは、ゲッターの真ん中にある場合には、ある発信者に返される
nonatomic
では、そのような保証は行われません。したがって、nonatomic
は "アトミック" よりもかなり高速です。
ない「原子」とは何のありませんを行うには、スレッドの安全性についていかなる保証を行うことです。一つは、任意のセッターが呼び出される前に、またはセッターに渡された値のいずれか - スレッドAが異なる値でセッターを呼び出すスレッドBとCと同時にゲッターを呼び出している場合、スレッドAが返される3つの値のいずれかを得ることができBとCで同様に、オブジェクトは、B又はC、伝えるために決してからの値で終わる可能性があります。
データの整合性を確保 - マルチスレッドプログラミングの主要な課題の一つは - 他の手段によって達成される
これに追加します:
また、複数の依存特性がプレイしているとき、スレッドの安全性を保証することはできません。単一のプロパティのatomicity
考えてみます:
@property(atomic, copy) NSString *firstName;
@property(atomic, copy) NSString *lastName;
@property(readonly, atomic, copy) NSString *fullName;
この場合には、スレッドAはsetFirstName:
を呼び出し、次にsetLastName:
を呼び出してオブジェクトの名前を変更することができます。一方、スレッドBはスレッドAの2回の呼び出しの間でfullName
を呼び出すことができますし、古い姓と相まって新しい最初の名前を受信します。
この問題に対処するには、ののトランザクション・モデルを必要としています。即ち依存プロパティが更新されている間、1がfullName
へのアクセスを除外することを可能にする同期化および/または除外のいくつかの他の種類ます。
他のヒント
これは、Appleのドキュメントで説明されていますが、以下実際に何が起こっているかのいくつかの例です。あなたは、プロパティがアトミックである「非アトミック」を指定しますが、「アトミック」明示的にエラーになります指定しない場合、「アトミック」のキーワードが存在しないことに注意してください。
//@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に低下させる、値を設定している場合は、それ以外の潜在的な競合状態があります。
読み取り専用のプロパティは、スカラー値またはオブジェクトであり、どのように維持するかどうかに応じて、これらの物事の仕組みの異なる多数の変異体、コピー、非アトミックなどが相互作用実際にあります。一般的には、プロパティシンセサイザーだけですべての組み合わせについて、「正しいこと」を行う方法を知っています。
アトミック
- はデフォルトの動作です
- 別のプロセスが変数にアクセスする前に、現在のプロセスが CPU によって確実に完了するようにします。
- プロセスが完全に完了することが保証されるため、高速ではありません
非アトミック
- はデフォルトの動作ではありません
- 高速化 (合成コードの場合、つまり @property と @synthesize を使用して作成された変数の場合)
- スレッドセーフではない
- 2 つの異なるプロセスが同じ変数に同時にアクセスすると、予期しない動作が発生する可能性があります
違いを理解する最も良い方法は、次の例を使用することです。
「name」というアトミック文字列プロパティがあるとします。 [self setName:@"A"]
スレッド A から呼び出します [self setName:@"B"]
スレッド B から呼び出します [self name]
スレッド C からの場合、異なるスレッド上のすべての操作はシリアルに実行されます。つまり、1 つのスレッドがセッターまたはゲッターを実行している場合、他のスレッドは待機することになります。
これにより、プロパティ "name" の読み取り/書き込みが安全になりますが、別のスレッド D が呼び出すと、 [name release]
同時に、ここではセッター/ゲッター呼び出しが関与していないため、この操作によりクラッシュが発生する可能性があります。つまり、オブジェクトは読み取り/書き込みセーフ (ATOMIC) ですが、別のスレッドが同時に任意の種類のメッセージをオブジェクトに送信できるため、スレッドセーフではありません。開発者は、そのようなオブジェクトのスレッドセーフを確保する必要があります。
プロパティ「name」が非アトミックである場合、上記の例のすべてのスレッド (A、B、C、D) が同時に実行され、予測できない結果が生成されます。アトミックの場合、A、B、C のいずれかが最初に実行されますが、D は並行して実行できます。
構文とセマンティクスは、この質問に対する他の優れた回答によってすでに明確に定義されています。なぜなら 実行 そして パフォーマンス 詳細がよくわかっていないので、回答を追加します。
これら 3 つの機能の違いは何ですか?
私は常にアトミックをデフォルトとして非常に興味深いと考えていました。抽象化レベルでは、100% のスレッドセーフを達成するための手段としてクラスのアトミック プロパティを使用することに取り組んでいますが、これは例外的なケースです。本当に正しいマルチスレッド プログラムの場合、プログラマによる介入がほぼ確実に必要になります。一方、パフォーマンスの特性と実行についてはまだ詳しく説明されていません。何年にもわたって高度にマルチスレッド化されたプログラムをいくつか書いてきたので、私は自分のプロパティを次のように宣言していました。 nonatomic
ずっと、アトミックはどんな目的にも賢明ではなかったからです。原子および非原子の特性の詳細についての議論中 この質問, プロファイリングを行ったところ、興味深い結果が得られました。
実行
わかりました。最初に明確にしておきたいのは、ロックの実装は実装定義であり、抽象化されているということです。ルイが使うのは @synchronized(self)
彼の例では、これが混乱の一般的な原因であると私は見てきました。実装はそうではありません 実は 使用 @synchronized(self)
;オブジェクトレベルを使用します スピンロック. 。Louis のイラストは、私たちがよく知っている構成要素を使用した高レベルのイラストに適していますが、次のようなものは使用しないことを知っておくことが重要です。 @synchronized(self)
.
もう 1 つの違いは、アトミック プロパティがゲッター内でオブジェクトの保持/解放を繰り返すことです。
パフォーマンス
興味深い部分は次のとおりです。アトミックなプロパティ アクセスを使用したパフォーマンス 争われていない (例えば。シングルスレッド) の場合は、場合によっては非常に高速になることがあります。理想的とは言えないケースでは、アトミック アクセスの使用には、アトミック アクセスのオーバーヘッドの 20 倍を超えるコストがかかる可能性があります。 nonatomic
. 。一方、 争われた 7 スレッドを使用した場合、3 バイトの構造体 (2.2 GHz) では 44 倍遅くなりました。 コア i7 クアッドコア、x86_64)。3 バイトの構造体は、非常に遅いプロパティの例です。
興味深い補足:3 バイトの構造体のユーザー定義アクセサーは、合成されたアトミック アクセサーより 52 倍高速でした。または、合成された非アトミック アクセサーの 84% の速度です。
係争中の訴訟の対象は 50 回を超える場合もあります。
実装には多数の最適化とバリエーションがあるため、これらの状況における現実世界への影響を測定することは非常に困難です。「プロファイリングして問題ないと思わない限り、信頼してください」というようなことをよく聞くかもしれません。抽象度が高いため、実際の効果を測定するのは非常に困難です。プロファイルから実際のコストを収集するには非常に時間がかかり、抽象化のため非常に不正確になる可能性があります。同様に、ARC と MRC では大きな違いが生じる可能性があります。
それで、一歩下がってみましょう、 ない プロパティ アクセスの実装に焦点を当て、次のようなよくある容疑者を含めます。 objc_msgSend
, 、そして、 NSString
ゲッターイン 争われていない ケース (秒単位の値):
- MRCの |非原子 |手動で実装されたゲッター:2
- MRCの |非原子 |合成ゲッター:7
- MRCの |アトミック |合成ゲッター:47
- アーク |非原子 |合成ゲッター:38(注:ARC はここで参照カウントの循環を追加します)
- アーク |アトミック |合成ゲッター:47
おそらくご想像のとおり、参照カウントのアクティビティ/サイクリングは、アトミックおよび ARC に大きく貢献しています。係争中の訴訟でも大きな違いが見られるでしょう。
パフォーマンスには細心の注意を払っていますが、それでも言います。 セマンティクスが第一です!. 。一方、パフォーマンスは多くのプロジェクトにとって優先順位が低いです。ただし、使用するテクノロジの実行の詳細とコストを知っていて損はありません。自分のニーズ、目的、能力に応じて適切なテクノロジーを使用する必要があります。これにより、数時間の比較が節約され、プログラムを設計する際に、より適切な情報に基づいた決定ができるようになれば幸いです。
アトミック = スレッドの安全性
非原子的 = スレッドセーフなし
スレッドの安全性:
インスタンス変数は、ランタイム環境によるそれらのスレッドの実行のスケジューリングやインターリーブに関係なく、呼び出しコード側で追加の同期やその他の調整を行わなくても、複数のスレッドからアクセスされたときに正しく動作する場合、スレッドセーフです。
私たちの文脈では:
スレッドがインスタンスの値を変更すると、変更された値はすべてのスレッドで利用可能になり、一度に 1 つのスレッドのみが値を変更できます。
使用する場所 atomic
:
インスタンス変数がマルチスレッド環境でアクセスされる場合。
の含意 atomic
:
それほど速くはありません nonatomic
なぜなら nonatomic
ランタイムからのウォッチドッグの作業は必要ありません。
使用する場所 nonatomic
:
インスタンス変数が複数のスレッドによって変更されない場合は、それを使用できます。パフォーマンスが向上します。
私は<のhref =「http://archive.atomicmpc.com.au/forums.asp?s=2&c=10&t=4594」のrel = "noreferrer原子と非アトミック性質のかなりよく置か説明を見つけました「>ここを。ここでは同じからいくつかの関連するテキストがあります:
「原子」は破壊されないことを意味します。 OS /プログラミング用語では、原子関数呼び出しは中断できないものです - 全体の機能が実行され、それが完全になるまでスイッチングOSの通常のコンテキストでCPUからスワップ・アウトされませんする必要があります。念のためにあなたが知らなかった:CPUは一度に一つのことを行うことができるので、OSは少し時間スライス内のすべての実行中のプロセスにCPUへのアクセスを回転させる、のの錯覚のを与えることマルチタスク。 CPUスケジューラは、缶(とない)、実行中の任意の時点で処理を中断 - でも、ミッド関数呼び出しで。だから、2つのプロセスが同時に変数を更新しようとすることができ、共有カウンタ変数を更新するような行為のために、彼らは「アトミック」を実行しなければならない、すなわち、それぞれの更新アクションは、他のプロセスが上にスワップすることができます前に、その全体で終了する必要がありますCPUます。
私は、この場合の原子が属性リーダー方法が中断されないことを意味していることを推測するだろうだから - 効果に変数(複数可)の方法による価値の半分を変更することはできません方法で読まれていることを意味し、いくつかの他のスレッド/コール理由/機能は、CPUに交換されます。
atomic
変数が中断することができないので、、任意の時点でそれらに含まれる値は、(スレッドロック)このスレッドのロックを確保することは、それらへのアクセス遅くになり、ものの、の破損していないのあることが保証されます。 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
はデフォルトの動作です- ガベージ コレクションが行われていない環境でのアトミック アクセサー (つまり、restart/release/autorelease を使用する場合) は、別のスレッドが値の正しい設定/取得を妨げないようにロックを使用します。
- 実際にはキーワードではありません。
例:
@property (retain) NSString *name; @synthesize name;
nonatomic
nonatomic
複数のスレッドが変数にアクセスすることを意味します (動的型)。nonatomic
スレッド安全ではありません。- でも性能は速い
nonatomic
はデフォルトの動作ではありません。を追加する必要があります。nonatomic
property 属性のキーワード。- 2 つの異なるプロセス (スレッド) が同じ変数に同時にアクセスすると、予期しない動作が発生する可能性があります。
例:
@property (nonatomic, retain) NSString *name; @synthesize name;
アトミック :
アトミックは、プロパティへのアクセスがアトミックな方法で実行されることを保証します。例えば。常に完全に初期化されたオブジェクトを返すため、あるスレッド上のプロパティの取得/設定は、別のスレッドがアクセスできる前に完了する必要があります。
次の関数が 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 とは異なり、完全に初期化されたオブジェクトが毎回返されるとは限りません。
長所:非常に高速な実行。
短所:マルチスレッドの場合、ガベージ値が発生する可能性があります。
最も簡単な答え:あなたの第二の二つの例の間に違いはありません。デフォルトでは、プロパティアクセサはアトミックです。
非ガベージコレクション環境で原子アクセサ(すなわち、保持/解放/自動解放を使用する場合)別のスレッドが正しい設定は/値の取得に干渉しないことを確実にするためにロックを使用します。
原子が一つだけスレッドが変数(静的タイプ)にアクセスします。アトミックは、スレッドセーフであるが、それは遅いです。
非アトミックは、複数のスレッドが変数(ダイナミック型)にアクセスします。非アトミックはスレッド安全ではありませんが、それは速いです。
アトミックとは スレッドセーフ, 、それは 遅い そしてそれ よく保証します(保証はありません) 同じゾーン上でアクセスを試行しているスレッドの数に関係なく、ロックされた値のみが提供されるということです。アトミックを使用する場合、この関数内に記述されたコードはクリティカル セクションの一部となり、一度に 1 つのスレッドのみが実行できます。
スレッドの安全性を保証するだけです。それを保証するものではありません。 私が言いたいのは、あなたの車のために専門のドライバーを雇ったとしても、それでもその車が事故に遭わないという保証はないということです。ただし、可能性は依然としてわずかです。
アトミック - 分解できないため、結果は期待されます。非アトミックの場合 - 別のスレッドがメモリ ゾーンにアクセスすると、メモリ ゾーンが変更される可能性があるため、予期しない結果が生じます。
コードトーク:
アトミックはプロパティのゲッターとセッターをスレッドセーフにします。たとえば、次のように書いた場合:
self.myProperty = value;
スレッドセーフです。
[myArray addObject:@"Abc"]
スレッドセーフではありません。
「アトミック」というキーワードはありません
@property(atomic, retain) UITextField *userName;
上記のように使用できます
@property(retain) UITextField *userName;
スタックオーバーフローの質問を参照してください。 @property(atomic,retain)NSString *myString を使用すると問題が発生します.
の デフォルト は atomic
, これは、プロパティを使用するたびにパフォーマンスが低下しますが、スレッドセーフであることを意味します。Objective-C が行うことは、セッター/ゲッターが実行されている限り、実際のスレッドのみが変数にアクセスできるようにロックを設定することです。
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;
キーワードは最初のプロパティ属性として記述する必要はまったくありません。
これは、プロパティ全体がスレッドセーフであることを意味するわけではないことを忘れないでください。セッター/ゲッターのメソッド呼び出しのみです。ただし、セッターを使用し、その後にゲッターを 2 つの異なるスレッドで同時に使用すると、それも壊れる可能性があります。
アトミック(デフォルト)
原子力がデフォルトです:あなたは何も入力しない場合は、あなたの財産があります アトミック。アトミックプロパティは、あなたがしようとした場合から読み取ることが保証されています それは、あなたが有効な値を取り戻すだろう。これは、任意の保証を行いません。 その値があるかもしれないが、あなたは良いデータを取り戻すだろう、ないものについて ちょうどジャンクメモリ。あなたは複数持っている場合これはあなたがすることができますすることです 単一の変数を指すスレッドまたは複数のプロセス、1 スレッドを読むことができますし、別のスレッドが書くことができます。彼らは同じでヒットした場合 時間は、読者のスレッドが2つの値のいずれかを取得することが保証されています。 変更前または変更後のいずれか。アトミック何しません あなたはあなたにどの程度、それらの値の保証の任意の並べ替えをされ与えます 得る可能性があります。アトミックは本当に一般的に、スレッドセーフであることと混同されます それは正しくありません。あなたは、スレッドの安全性を保証する必要があります 他の方法。しかし、原子はあなたが読んしようとすることを保証します、 あなたは、値のいくつかの種類を取り戻すます。
アトミック
フリップ側では、非アトミック、あなたはおそらく推測できるように、単に、意味 「その原子のものを行うません。」あなたはその保証されて失う何 常に何かを取り戻します。あなたは、途中で読むしようとした場合 書き、あなたはゴミデータを取り戻すことができました。しかし、一方で、あなたが行きます 少し速いです。原子の性質は、いくつかの魔法を行う必要があるため あなたが値を取り戻すことを保証するために、彼らは少し遅くなります。もし それはあなたが多くのことをアクセスしている、あなたが落下する場合があり財産であります あなたがその速度を負担していないことを確認するために、アトミックにダウン ペナルティます。
の詳細はこちらをご覧ください: https://realm.io/news/tmi-objective-c-プロパティの属性/ の
あなたは、あなたがアトミックとアトミック属性間の違いを見ることができるだろう、マルチスレッドコードであなたの財産を使用している場合。アトミックは、原子と原子がスレッドセーフであるよりも高速で、アトミックではない。
Vijayendra Tripathiは既にマルチスレッド環境のための例を与えている。
- -アトミックとは、1 つのスレッドのみが変数 (静的型) にアクセスすることを意味します。
- - アトミックはスレッドセーフです。
- -ただしパフォーマンスは遅い
宣言方法:
アトミックがデフォルトなので、
@property (retain) NSString *name;
実装ファイル内の AND
self.name = @"sourov";
3 つのプロパティに関連するタスクが次のとおりであるとします。
@property (retain) NSString *name;
@property (retain) NSString *A;
@property (retain) NSString *B;
self.name = @"sourov";
すべてのプロパティは (非同期のように) 並行して動作します。
スレッドから「名前」を呼び出した場合 あ,
そして
同時に電話すると
[self setName:@"Datta"]
スレッドから B,
*name プロパティが非アトミックの場合 それから
- Aに対して「Datta」という値を返します。
- Bに対して「Datta」という値を返します。
これが、非アトミックがスレッドアンセーフと呼ばれる理由です。ただし、並列実行のためパフォーマンスが高速です。
*name プロパティがアトミックの場合
- A の値「Sourov」が保証されます。
- 次に、Bの値「Datta」を返します。
アトミックがスレッドセーフと呼ばれるのはこのためです そしてそれが読み書き安全と呼ばれる理由です
このような場合の操作は逐次実行されます。 そしてパフォーマンスが遅い
- 非アトミックとは、複数のスレッドが変数 (動的型) にアクセスすることを意味します。
- 非アトミックはスレッドアンセーフです。
- しかし、パフォーマンスは速いです
-非アトミックはデフォルトの動作ではないため、プロパティ属性に非アトミックキーワードを追加する必要があります。
In Swiftの場合 Swift プロパティが ObjC の意味で非アトミックであることを確認する。理由の 1 つは、プロパティごとのアトミック性がニーズに十分であるかどうかを検討するためです。
参照: https://forums.developer.apple.com/thread/25642
詳細については、ウェブサイトをご覧くださいhttp://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
あなたが始める前に:新しいライターを実行するには、メモリ内のすべてのオブジェクトをメモリから割り当て解除する必要があることを知っておく必要があります。紙に書くのと同じように、単に何かの上に書くだけでは済みません。あなた しなければならない まず消去 (割り当て解除) してから、書き込むことができます。消去が完了(または半分完了)した時点で何も行われていない場合 まだ 書かれた (または書きかけた) ものを読もうとすると、非常に問題が生じる可能性があります。アトミックと非アトミックは、この問題をさまざまな方法で処理するのに役立ちます。
最初に読む これ 質問してから読んでください ブムさんの答え. 。さらに、私の要約を読んでください。
atomic
必ず保証します
- 2 人の異なる人が同時に読み書きしたい場合、紙はただ燃えるだけではありません。--> 競合状態であっても、アプリケーションがクラッシュすることはありません。
- 1 人が書こうとしていて、8 文字のうち 4 文字しか書いていない場合、途中で読み取ることはできず、8 文字すべてが書かれた場合にのみ読み取りが可能です --> 読み取り(取得)は行われません。 「まだ書き込み中のスレッド」、つまり書き込まれるバイト数が 8 バイトで、4 バイトだけが書き込まれる場合、その瞬間までは、そこから読み取ることはできません。しかし、クラッシュしないと言っているので、その場合は、 自動解放される 物体。
- もし 前に あなたに書いています 持っている 以前に紙に書いたものを消したら、誰かがあなたのことを読みたがりました できる まだ読んでいます。どうやって?Mac OS のゴミ箱に似たものから読み取ることになります (ゴミ箱はまだ 100% 消去されていないため、途方に暮れています) ---> ThreadB が既に書き込みの割り当てを解除されている間に ThreadA が読み取る場合、次のようになります。 ThreadB によって完全に書き込まれた最終値からの値、または自動解放プールから何かを取得します。
保持カウントは、Objective-C でメモリを管理する方法です。オブジェクトを作成すると、保持カウントは 1 になります。送信時 オブジェクトが保存メッセージである場合、その保存カウントは 1 ずつ増加します。いつ オブジェクトにリリース・メッセージを送信すると、その保持カウントがデクリメントされます 1で。オブジェクトを送信すると、 自動解放メッセージ, 、その保持カウント は、将来のある時点で 1 ずつ減少します。オブジェクトが保持する場合 count は 0 に減らされ、割り当てが解除されます。
- アトミック しません スレッドの安全性を保証しますが、スレッドの安全性を実現するのに役立ちます。スレッド セーフは、コードの書き方、どのスレッド キューから読み取り/書き込みを行うかに関係します。クラッシュしないマルチスレッドを保証するだけです。
何?!マルチスレッド化されており、 スレッドセーフティ 違う?
はい。マルチスレッドとは次のことを意味します。複数のスレッドが共有データを同時に読み取ることができ、クラッシュすることはありませんが、自動解放されていない値から読み取っていないことは保証されません。スレッドセーフにより、読み取った内容が自動解放されないことが保証されます。デフォルトですべてをアトミックにしない理由は、パフォーマンスにコストがかかることと、ほとんどの場合スレッド セーフが実際には必要ないためです。コードのいくつかの部分ではこれが必要であり、それらのいくつかの部分では、ロック、ミューテックス、または同期を使用してスレッドセーフな方法でコードを記述する必要があります。
nonatomic
- Mac OS のゴミ箱のようなものはないので、常に値を取得するかどうかは誰も気にしません (<-- これは潜在的にクラッシュにつながる可能性があります)。また、誰かがあなたの書き込みの途中で読み取ろうとしても誰も気にしません (ただし、メモリに中途半端に書き込むことは、紙に中途半端に書き込むこととは大きく異なります。メモリ上では以前の馬鹿げた値が得られる可能性がありますが、紙では書き込まれた内容の半分しか表示されません) --> クラッシュしないことを保証するものではありません。自動解放メカニズムは使用しません。
- 書き込まれた完全な値が読み取れることは保証されません。
- アトミックよりも高速です
全体として、次の 2 つの点で異なります。
自動解放プールの有無によってクラッシュするかどうか。
「まだ終了していない書き込みまたは空の値」の途中での読み取りを許可するか、許可せず、値が完了していない場合にのみ読み取りを許可します。 完全に 書かれた。
アトミックプロパティは関係なく、その上にゲッター&セッターをやっているどのように多くのスレッドを完全に初期化値を保持することが保証されます。
非アトミック・プロパティは、同じ値が異なるスレッドから同時にアクセスされた場合に何が起こるかについては何の保証と、単に設定または直接値を返すアクセサを合成することを指定します。
原子が一つだけスレッドが時間(静的タイプ)での変数にアクセスできることを意味します。アトミックは、スレッドセーフであるが、それは遅いです。
非アトミックは、複数のスレッドが同時に(ダイナミック型)で変数にアクセスできることを意味します。非アトミックはスレッド安全ではありませんが、それは速いです。
原子性 atomic (デフォルト)
アトミックがデフォルトです。何も入力しない場合、プロパティは アトミック。アトミックプロパティは、 それを使用すると、有効な値が返されます。いかなる保証も行いません その値が何であるかについてですが、あなたは良いデータを返すでしょう、そうではありません ただのジャンクメモリ。これにより、複数の スレッドまたは複数のプロセスが 1 つの変数 (1 つの変数) スレッドは読み取り可能で、別のスレッドは書き込みが可能です。それらが同時にヒットした場合 timeの場合、リーダースレッドは次の2つの値のいずれかを取得することが保証されます。変更前でも変更後でも。アトミックにないもの 与えることは、それらの値のどれについて何らかの保証です 得るかもしれません。アトミックはスレッドセーフであることと混同されがちですが、 そして、それは正しくありません。スレッドセーフを保証する必要があります 他の方法。ただし、アトミックは、読み取ろうとすると、 あなたはある種の価値を取り戻します。
非原子的な
反対に、非原子とは、おそらくご想像のとおり、 「そんなアトミックなことはするな」あなたが失うのは、あなたが 常に何かを取り戻します。途中で読もうとすると、 書き込むと、ガベージデータを取り戻すことができます。しかし、その一方で、あなたは行きます 少し速くなりました。なぜなら、原子の性質は何らかの魔法を働かなければならないからです 値を確実に返すために、少し遅くなります。もし アクセスが多い物件なので、落とした方がいいかもしれません 非アトミックに下げて、その速度が発生していないことを確認します 罰。アクセス
礼儀 https://academy.realm.io/posts/tmi-objective-c-property-attributes/
アトミック プロパティ属性 (アトミックおよび非アトミック) は、対応する Swift プロパティ宣言には反映されませんが、インポートされたプロパティが Swift からアクセスされる場合、Objective-C 実装のアトミック性の保証は引き続き保持されます。
したがって、Objective-C でアトミック プロパティを定義すると、Swift で使用されるときにもアトミックのままになります。
礼儀https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c
は、スレッドが安全であると読み取り専用にすることを意味します。あなたがアトミック使用している場合は、複数のスレッドが変数にアクセスし、スレッド安全ではないこと、それは、高速な実行の読み取りを行っておよび書き込み操作されます。これは、動的な型である。
真実は、彼らは、原子プロパティを実装するためにスピンロックを使用することです。以下のようにコード:
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);
}
原子の性質 :- アトミック プロパティが割り当てられた変数、つまりスレッド アクセスが 1 つだけあり、スレッド セーフでパフォーマンスの観点から優れている場合、デフォルトの動作になります。
非原子プロパティ :- アトミック プロパティが割り当てられた変数、つまりマルチスレッド アクセスがあり、スレッド セーフではなく、パフォーマンスの観点から遅くなる場合、デフォルトの動作が行われ、2 つの異なるスレッドが同時に変数にアクセスしたい場合は、予想外の結果。
全体の混乱を簡素化するために、私たちは、ミューテックスのロックを理解してみましょう。
相互排他ロックは、名前の通り、オブジェクトの可変性をロックします。オブジェクトはクラスによってアクセスされるのであれば、他のクラスが同じオブジェクトにアクセスすることはできません。
IOSの、@sychronise
はまた、FIFOモードで機能し、流れは同じインスタンスを共有する二つのクラスに影響されない保証.Now相互排他ロックを提供します。タスクは、メインスレッド上にある場合は、それはあなたのUIを保持し、性能を低下させ得るような原子の性質を利用してアクセスするオブジェクトを避けています。
アトミック:。NSLOCKを使用してスレッドをロックすることにより、スレッドの安全性を確認してください。
非アトミック:NOスレッドロック機構が存在しないようにスレッドの安全性を保証しない
。