回答:
最後の2つは同じです。「アトミック」はデフォルトの動作です(実際にはキーワードではないことに注意してください。これは - nonatomic
atomic
がないことによってのみ指定されます -llvm / clangの最近のバージョンでキーワードとして追加されました)。
メソッドの実装を@synthesizingしていると仮定すると、アトミック対非アトミックは生成されたコードを変更します。独自のセッター/ゲッターを作成している場合、atomic / nonatomic / retain / assign / copyは単なる助言です。(注:LLVMの最近のバージョンでは、@ synthesizeがデフォルトの動作になりました。インスタンス変数を宣言する必要もありません。インスタンス変数も自動的に合成_
され、誤って直接アクセスしないように名前の先頭に追加されます)。
「アトミック」の場合、合成されたセッター/ゲッターは、他のスレッドでのセッターアクティビティに関係なく、常に値全体がゲッターから返されるか、セッターによって設定されるようにします。つまり、スレッドBがセッターを呼び出している間にスレッドAがゲッターの途中にある場合、実際の実行可能な値(自動解放されたオブジェクト)がAの呼び出し元に返されます。
ではnonatomic
、そのような保証は行われません。したがって、nonatomic
「アトミック」よりもかなり高速です。
「アトミック」が行わないことは、スレッドの安全性を保証することです。スレッドAがスレッドBとCが異なる値でセッターを呼び出すと同時にゲッターを呼び出している場合、スレッドAは、3つの値のいずれか1つを返します。同様に、オブジェクトは、BまたはCからの値で終了する可能性があり、伝える方法がありません。
マルチスレッドプログラミングの主な課題の1つであるデータの整合性を保証することは、他の方法でも実現できます。
これに追加:
atomicity
複数の依存プロパティが関係している場合、単一のプロパティのスレッド安全性も保証できません。
検討してください:
@property(atomic, copy) NSString *firstName;
@property(atomic, copy) NSString *lastName;
@property(readonly, atomic, copy) NSString *fullName;
この場合、スレッドAはを呼び出してsetFirstName:
からを呼び出すことにより、オブジェクトの名前を変更している可能性がありますsetLastName:
。その間、スレッドBはfullName
スレッドAの2つの呼び出しの間に呼び出しを行い、新しい姓と古い姓を受け取ります。
これに対処するには、トランザクションモデルが必要です。つまりfullName
、依存するプロパティが更新されている間、アクセスを除外できる他の種類の同期や除外です。
@property NSArray* astronomicalEvents;
示します。UI に表示するデータをリストするがあります。アプリケーションが起動すると、ポインターが空の配列を指し、アプリはWebからデータをプルします。(別のスレッドで)Webリクエストが完了すると、アプリは新しい配列を作成し、プロパティを新しいポインター値にアトミックに設定します。それはスレッドセーフであり、何かが欠落していない限り、ロックコードを記述する必要はありませんでした。私にはかなり便利なようです。
atomic
クロススレッドの半値読み取りを防ぎます。(それは追跡するのに楽しいバグでした。)
retain/autorelease
ダンスなしのオブジェクトを返します。スレッドBがオブジェクトを解放します。スレッドAがブームになります。 atomic
スレッドAが戻り値の強い参照(+1保持カウント)を持つようにします。
これは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に低下した場合、潜在的な競合状態になります。
プロパティがスカラー値であるかオブジェクトであるか、および保持、コピー、読み取り専用、非アトミックなどがどのように相互作用するかに応じて、これらがどのように機能するかについて、実際には多数の異なるバリアントがあります。一般に、プロパティシンセサイザは、すべての組み合わせに対して「正しいこと」を行う方法を知っています。
@property (assign) id delegate;
は何にも同期されません(iOS SDK GCC 4.2 ARM -Os
)。これは、との間に競合があることを意味[self.delegate delegateMethod:self];
しfoo.delegate = nil; self.foo = nil; [super dealloc];
ます。参照してくださいstackoverflow.com/questions/917884/...
_val
/ val
が何であるかわかりませんが、いいえ、本当にではありません。アトミックcopy
/ retain
プロパティのゲッターは、セッターが別のスレッドで呼び出されたためにrefcountがゼロになるオブジェクトを返さないことを確認する必要があります。上書きして解放し、自動解放して保持のバランスを取ります。これは基本的に、ゲッターとセッターの両方がロックを使用する必要があることを意味します(メモリレイアウトが修正された場合、CAS2命令で実行できるはずです。悲しいことに-retain
、メソッド呼び出しです)。
違いを理解する最良の方法は、次の例を使用することです。
「name」というアトミック文字列プロパティがあり、[self setName:@"A"]
スレッドAから呼び出し[self setName:@"B"]
、スレッドB [self name]
から呼び出し、スレッドCから呼び出す場合、異なるスレッドでのすべての操作は順次実行されます。つまり、1つのスレッドがセッターを実行しているかどうかまたはゲッター、他のスレッドが待機します。
これにより、プロパティ "name"の読み取り/書き込みは安全になりますが、別のスレッドDが[name release]
同時に呼び出されると、この操作に関係するsetter / getter呼び出しがないため、この操作がクラッシュする可能性があります。つまり、オブジェクトは読み取り/書き込みセーフ(ATOMIC)ですが、別のスレッドがオブジェクトに任意のタイプのメッセージを同時に送信できるため、スレッドセーフではありません。開発者は、そのようなオブジェクトのスレッドセーフを確保する必要があります。
プロパティ「name」が非アトミックである場合、上記の例のすべてのスレッド-A、B、C、およびDが同時に実行され、予測できない結果が生じます。アトミックの場合、A、B、またはCのいずれかが最初に実行されますが、Dは引き続き並行して実行できます。
構文とセマンティクスは、この質問に対する他の優れた回答によってすでに明確に定義されています。実行とパフォーマンスは詳細に記述されていないため、回答を追加します。
これら3つの機能的な違いは何ですか?
私はいつもデフォルトをかなり好奇心が強いと考えていました。私たちが取り組んでいる抽象化レベルでは、クラスのアトミックプロパティをビヒクルとして使用して100%スレッドセーフティを達成することは、例外的なケースです。真に正しいマルチスレッドプログラムの場合、プログラマによる介入はほぼ確実に必要です。一方、パフォーマンス特性と実行については、まだ詳しく説明されていません。何年にもわたってマルチスレッド化されたプログラムをいくつか書いてきnonatomic
たので、アトミックはどんな目的にも向いていないので、自分のプロパティをずっと宣言していました。この質問の原子的および非原子的特性の詳細の議論中に、私はいくつかのプロファイリングを行っていくつかの奇妙な結果に遭遇しました。
実行
OK。最初に明らかにしたいのは、ロックの実装が実装定義であり、抽象化されていることです。ルイは@synchronized(self)
彼の例で使用します-私はこれを一般的な混乱の原因として見ました。実装は実際には使用しません@synchronized(self)
。オブジェクトレベルのスピンロックを使用します。ルイのイラストは、私たちがよく知っている構成を使用した高レベルのイラストに適していますが、使用しないことを知っておくことが重要です@synchronized(self)
です。
もう1つの違いは、アトミックプロパティはゲッター内でオブジェクトを保持/解放するということです。
パフォーマンス
これが興味深い部分です。競合しない(たとえば、シングルスレッド)ケースでアトミックプロパティアクセスを使用したパフォーマンスは、場合によっては非常に高速になることがあります。理想的ではない場合では、アトミックアクセスを使用すると、のオーバーヘッドの20倍以上のコストがかかる可能性がありnonatomic
ます。7スレッドを使用したコンテストのケースは、3バイトの構造体(2.2 GHz Core i7クアッドコア、x86_64)の。3バイトの構造体は、非常に遅いプロパティの例です。
興味深い補足:3バイトの構造体のユーザー定義のアクセサーは、合成されたアトミックアクセサーよりも52倍高速でした。または合成された非アトミックアクセサーの84%の速度。
争われたケースのオブジェクトも50回を超える可能性があります。
実装の最適化とバリエーションの数が多いため、これらのコンテキストで実際の影響を測定することは非常に困難です。「プロファイリングして問題がない限り、信頼してください」のようなメッセージをよく耳にします。抽象化レベルのため、実際の影響を測定することは実際には非常に困難です。プロファイルから実際のコストを収集することは、非常に時間がかかる可能性があり、抽象化のため、非常に不正確です。同様に、ARCとMRCは大きな違いをもたらす可能性があります。
そこで、プロパティアクセスの実装に焦点を当てずに一歩objc_msgSend
下がって、のような通常の容疑者を含めてNSString
、競合しないケースでのゲッターへの多くの呼び出しの実際の高レベルの結果(秒単位の値)を調べます。
おそらくご想像のとおり、参照カウントのアクティビティ/循環は、アトミックおよびARCの下での重要な貢献者です。また、競合するケースでは大きな違いが見られます。
パフォーマンスには細心の注意を払っていますが、それでもセマンティクスを第一に考えています。。一方、多くのプロジェクトでは、パフォーマンスの優先度は低くなっています。ただし、使用するテクノロジーの実行の詳細とコストを知っていても、害はありません。ニーズ、目的、および能力に適したテクノロジーを使用する必要があります。うまくいけば、これにより数時間の比較が節約され、プログラムを設計するときに、より適切な情報に基づいた決定を行うのに役立ちます。
NSString
不滅ではない シングルスレッドの競合しないケースを対象としています。- -ARC atomic (BASELINE): 100% -ARC nonatomic, synthesised: 94% -ARC nonatomic, user defined: 86% -MRC nonatomic, user defined: 5% -MRC nonatomic, synthesised: 19% -MRC atomic: 102%
今日の結果は少し異なります。@synchronized
比較はしていませんでした。@synchronized
は意味的に異なり、重要な並行プログラムがある場合、私はそれを良いツールとは見なしません。スピードが必要な場合は避けてください@synchronized
。
原子 =スレッドセーフ
非アトミック =スレッドセーフなし
インスタンス変数は、ランタイム環境によるそれらのスレッドの実行のスケジューリングやインターリーブに関係なく、複数のスレッドからアクセスされたときに正しく動作し、呼び出し側のコードで追加の同期やその他の調整が行われていなければ、スレッドセーフです。
スレッドがインスタンスの値を変更した場合、変更された値はすべてのスレッドで使用でき、一度に1つのスレッドのみが値を変更できます。
atomic
:マルチスレッド環境でインスタンス変数にアクセスする場合。
atomic
:ないの速さでnonatomic
あるためnonatomic
、実行時からその上の任意のウォッチドッグ作業を必要としません。
nonatomic
:インスタンス変数が複数のスレッドによって変更されない場合は、それを使用できます。パフォーマンスが向上します。
私はここに原子と非原子の特性のかなりよく説明された説明を見つけました。以下は、同じものからの関連テキストです。
「アトミック」とは、分解できないことを意味します。OS /プログラミング用語では、アトミック関数呼び出しは中断できないものです-関数全体を実行する必要があり、完了するまで、OSの通常のコンテキスト切り替えによってCPUからスワップアウトされません。あなたが知らなかった場合に備えて:CPUは一度に1つのことしかできないため、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
デフォルトの動作です例:
@property (retain) NSString *name;
@synthesize name;
nonatomic
nonatomic
複数のスレッドが変数にアクセスすることを意味します(動的タイプ)。nonatomic
スレッドセーフではありません。nonatomic
デフォルトの動作ではありません。nonatomic
property属性にキーワードを追加する必要があります。例:
@property (nonatomic, retain) NSString *name;
@synthesize name;
Atomicは、プロパティへのアクセスがアトミックな方法で実行されることを保証します。たとえば、常に完全に初期化されたオブジェクトを返します。あるスレッドのプロパティの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つの例に違いはありません。デフォルトでは、プロパティアクセサーはアトミックです。
ガベージコレクションされていない環境(つまり、retain / release / autoreleaseを使用する場合)のアトミックアクセサーは、ロックを使用して、別のスレッドが値の正しい設定/取得に干渉しないようにします。
マルチスレッドアプリを作成する際の詳細やその他の考慮事項については、AppleのObjective-C 2.0ドキュメントの「パフォーマンスとスレッド」セクションを参照してください。
Atomicはスレッドセーフであり、遅く、十分に保証されます(保証されません)、同じゾーンでアクセスを試行しているスレッドの数に関係なく、ロックされた値のみが提供さ。アトミックを使用する場合、この関数内に記述されたコードの一部は、一度に1つのスレッドしか実行できないクリティカルセクションの一部になります。
スレッドの安全性を保証するだけです。それを保証するものではありません。つまり、あなたはあなたの車のエキスパートドライバーを雇っていますが、それでも車が事故に遭わないことを保証するものではありません。ただし、確率はわずかです。
原子-分解できないため、結果は予想されます。非アトミック-別のスレッドがメモリゾーンにアクセスすると変更される可能性があるため、予期しない結果になります。
コードトーク:
プロパティのアトミックなゲッターとセッターをスレッドセーフにします。たとえば、あなたが書いた場合:
self.myProperty = value;
スレッドセーフです。
[myArray addObject:@"Abc"]
スレッドセーフではありません。
「原子」というキーワードはありません
@property(atomic, retain) UITextField *userName;
上記のように使用できます
@property(retain) UITextField *userName;
@property(atomic、retain)NSString * myStringを使用すると問題が発生する Stack Overflowの質問を参照してください。
アトミック(デフォルト)
Atomicがデフォルトです。何も入力しない場合、プロパティはAtomicです。アトミックプロパティは、そこから読み取ろうとすると、有効な値が返されることが保証されています。その値が何であるかについては保証されませんが、ジャンクメモリだけでなく、適切なデータが返されます。これにより、1つの変数を指す複数のスレッドまたは複数のプロセスがある場合、1つのスレッドが読み取り、別のスレッドが書き込みを行うことができます。それらが同時にヒットした場合、リーダースレッドは、変更前または変更後の2つの値のいずれかを取得することが保証されます。アトミックがあなたに与えないものは、あなたがそれらの値のどれを得るかについての何らかの種類の保証です。Atomicは一般的にスレッドセーフであると混同されますが、それは正しくありません。他の方法でスレッドセーフを保証する必要があります。
非原子
反対に、おそらく非アトミックなことは、おそらく推測できるように、「そのアトミックなことをしないこと」を意味します。あなたが失うものは、あなたが常に何かを取り戻すという保証です。書き込みの途中で読み込もうとすると、ガベージデータを取り戻す可能性があります。しかし、その一方で、あなたは少し速く行きます。アトミックプロパティは、値が返されることを保証するために何らかの魔法をかける必要があるため、少し遅くなります。頻繁にアクセスしているプロパティである場合は、非アトミックにドロップダウンして、速度のペナルティが発生しないようにすることができます。
詳細はこちら:https : //realm.io/news/tmi-objective-c-property-attributes/
デフォルトはあります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つの異なるスレッドで同時にゲッターを使用した場合も、壊れる可能性があります。
始める前に:新しいライターを実行するには、メモリ内のすべてのオブジェクトをメモリから解放する必要があることを知っておく必要があります。紙に書いているように、単に何かの上に単に書くことはできません。最初にそれを消去(dealloc)する必要があり、次にそれに書き込むことができます。消去が完了(または半分が完了)し、まだ何も書き込まれていない(または半分が書き込まれている)ときに、読み込もうとすると、非常に問題が発生する可能性があります。アトミックおよび非アトミックは、この問題をさまざまな方法で処理するのに役立ちます。
まずこの質問を読んでから、Bbumの回答を読んでください。さらに、私の要約を読んでください。
atomic
常に保証します
保持カウントは、Objective-Cでメモリを管理する方法です。オブジェクトを作成すると、保持カウントは1になります。オブジェクトに保持メッセージを送信すると、保持カウントは1ずつ増加します。オブジェクトにリリースメッセージを送信すると、保持カウントは1ずつ減少します。オブジェクトに自動解放メッセージを送信します。その保持カウントは、将来のある段階で1ずつ減少します。オブジェクトの保持カウントが0に減ると、割り当てが解除されます。
何?!マルチスレッドとスレッドセーフティは異なりますか?
はい。マルチスレッドとは、複数のスレッドが共有データを同時に読み取ることができ、クラッシュしないことを意味しますが、自動解放されていない値から読み取っていないことを保証するものではありません。スレッドセーフでは、読み取った内容が自動的に解放されないことが保証されます。デフォルトですべてをアトミックにしない理由は、パフォーマンスコストがあり、ほとんどの場合、スレッドセーフを実際には必要としないためです。コードのいくつかの部分でそれが必要であり、それらのいくつかの部分では、ロック、ミューテックス、または同期を使用してスレッドセーフな方法でコードを記述する必要があります。
nonatomic
全体として、2つの点で異なります。
自動解放プールの有無によるクラッシュの有無。
「まだ完了していない書き込みまたは空の値」の途中で読み取ることを許可するか、または値が完全に書き込まれたときにのみ読み取りを許可および許可しない。
宣言する方法:
アトミックはデフォルトなので、
@property (retain) NSString *name;
AND実装ファイル内
self.name = @"sourov";
3つのプロパティに関連するタスクが
@property (retain) NSString *name;
@property (retain) NSString *A;
@property (retain) NSString *B;
self.name = @"sourov";
すべてのプロパティは(非同期のように)並行して機能します。
スレッドAから「名前」を呼び出すと、
そして
同時に電話すれば
[self setName:@"Datta"]
スレッドBから
* nameプロパティが非アトミックの場合
そのため、非アトミックはスレッドセーフでないと呼ばれますが、並列実行のため、パフォーマンスは高速です
* nameプロパティがアトミックの場合
これが、アトミックがスレッドセーフと 呼ばれる理由であり、それが読み取り/書き込みセーフと呼ばれる理由です。
このようなシチュエーション操作は順次実行されます。 そしてパフォーマンスが遅い
-非アトミックとは、複数のスレッドが変数(動的タイプ)にアクセスすることを意味します。
-非アトミックはスレッドに対して安全ではありません。
-しかし、パフォーマンスは速い
-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をご覧ください 。
atomic
はありません!スレッドの問題に対してより耐性がありますが、スレッドセーフではありません。それは単に値全体、つまり「正しい」値(バイナリレベル)を取得することを保証しますが、決してそれがビジネスロジックの現在の「正しい」値であることを保証しません(過去の値とあなたの論理では無効です)。
原子性(デフォルト)
Atomicがデフォルトです。何も入力しない場合、プロパティはAtomicです。アトミックプロパティは、そこから読み取ろうとすると、有効な値が返されることが保証されています。その値が何であるかについては保証されませんが、ジャンクメモリだけでなく、適切なデータが返されます。これにより、1つの変数を指す複数のスレッドまたは複数のプロセスがある場合、1つのスレッドが読み取り、別のスレッドが書き込みを行うことができます。それらが同時にヒットした場合、リーダースレッドは、変更前または変更後の2つの値のいずれかを取得することが保証されます。アトミックがあなたに与えないものは、あなたがそれらの値のどれを得るかについての何らかの種類の保証です。Atomicは一般的にスレッドセーフであると混同されますが、それは正しくありません。他の方法でスレッドセーフを保証する必要があります。
非原子
反対に、おそらく非アトミックなことは、おそらく推測できるように、「そのアトミックなことをしないでください」という意味です。あなたが失うものは、あなたが常に何かを取り戻すという保証です。書き込みの途中で読み込もうとすると、ガベージデータを取り戻す可能性があります。しかし、その一方で、あなたは少し速く行きます。アトミックプロパティは、値が返されることを保証するために何らかの魔法をかける必要があるため、少し遅くなります。頻繁にアクセスしているプロパティである場合は、非アトミックにドロップダウンして、速度のペナルティが発生しないようにすることができます。アクセス
礼儀https://academy.realm.io/posts/tmi-objective-c-property-attributes/
アトミシティプロパティの属性(アトミックおよび非アトミック)は、対応するSwiftプロパティ宣言には反映されませんが、Objective-C実装のアトミシティ保証は、インポートされたプロパティがSwiftからアクセスされた場合でも保持されます。
したがって、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);
}
混乱全体を単純化するために、mutexロックを理解しましょう。
ミューテックスロックは、名前のとおり、オブジェクトの可変性をロックします。したがって、オブジェクトがクラスによってアクセスされる場合、他のクラスは同じオブジェクトにアクセスできません。
iOS @sychronise
では、mutexロックも提供します。FIFOモードで機能し、同じインスタンスを共有する2つのクラスによってフローが影響を受けないようにします。ただし、タスクがメインスレッド上にある場合は、UIを保持してパフォーマンスを低下させる可能性があるため、アトミックプロパティを使用してオブジェクトにアクセスしないでください。
アトミックプロパティ:- アトミックプロパティで割り当てられた変数は、スレッドアクセスが1つだけであり、スレッドセーフであり、パフォーマンスの観点で優れている場合、デフォルトの動作になります。
非アトミックプロパティ:- アトミックプロパティで割り当てられた変数、つまりマルチスレッドアクセスがあり、スレッドセーフではなく、パフォーマンスの観点から遅くなる場合、デフォルトの動作があり、2つの異なるスレッドが同時に変数にアクセスする場合予期しない結果が生じます。