Objective-c-Eigenschaften für primitive Typen

7

In Objective-C Ist es jemals sinnvoll, eine Eigenschaft für einen primitiven Typ als nonatomic ?

anzugeben

Ich wundere mich über den Unterschied zwischen diesen beiden Eigenschaften:

%Vor%     
SundayMonday 17.10.2012, 15:53
quelle

3 Antworten

24

Die Antwort ist technisch JA, sie sind anders, aber praktisch NEIN sind sie nicht, es sei denn, Sie codieren Ihre eigenen Accessoren.

Lass es mich erklären. Für eine Objektzeigereigenschaft, sagen wir @property NSObject *foo , gibt es einen klaren und wichtigen Unterschied im Code, der erzeugt wird, wenn Sie die Accessoren synthetisieren. Dies wird in der Apple-Dokumentation beschrieben, auf die es hinweist dass die synthetisierten Accessoren das Objekt sperren , wenn die Eigenschaft atomar ist (wenn Sie nichtatomare angeben, wird sie standardmäßig atomar)

Also für Objekteigenschaften In einer sehr groben Nussschale: nichtatomare ist schneller aber nicht threadsafe, atomare (Sie können es nicht angeben, aber es ist die Standardeinstellung) ist Thread sicher, aber möglicherweise langsamer.

(Hinweis: Wenn Sie mit Java vertraut sind, können Sie nonatomic wie nicht verwenden, indem Sie synchronized angeben, und nicht , indem Sie nonatomic angeben. als würde synchronized angegeben, also atomic = synchronized)

Aber ein BOOL ist ein Primitiv - in der Tat ein C-Zeichen mit Vorzeichen, also sollte der Zugriff atomar sein, ohne das Objekt zu sperren, wie in Janos Antwort erwähnt. Wenn Sie also den Accessor synthetisieren, gibt es zwei Möglichkeiten: 1: Der Compiler ist intelligent und sieht, dass die Eigenschaft primitiv ist und vermeidet, sie zu sperren, und 2: Der Compiler sperrt das Objekt immer für atomare Eigenschaften

Soweit ich das sehen kann, ist das nirgendwo dokumentiert, also habe ich es versucht, indem ich die Generate- & gt; Assembly-Option in XCode benutzt und es verglichen habe. Die Antwort war nicht vollständig, aber nahe genug, um zu sagen, dass ich fast sicher bin, dass die Antwort # 1 ist, der Compiler ist schlau. Ich sage das, weil der Assemblierungscode, der für eine atomare Objekteigenschaft generiert wird, erheblich anders ist (mehr davon) als für eine nicht atomare Objekteigenschaft: das ist der gesamte Code zum Sperren des Objekts. Bei einer BOOL-Eigenschaft gab es dagegen nur eine einzige Zeile - ein einzelnes "mov", das nicht so aussieht, könnte einen Unterschied machen. Trotzdem frage ich mich. Interessanterweise besteht ein weiterer Unterschied darin, dass die atomare Version von BOOL einige zusätzliche kommentierte Umrisse zum Debuggen hat - daher behandelt der Compiler sie offensichtlich anders.

Trotzdem ist die Ähnlichkeit so, dass ich sagen würde, dass sie für praktische Zwecke gleich sind.

Aber sie sind technisch immer noch anders und können sich in einer anderen Bibliothek, die Sie gerade lesen (die Sie selbst nicht programmiert haben), wesentlich unterscheiden, wenn Sie die Implementierung nicht sehen können, und deshalb: atomisch Eigenschaften haben einen Vertrag . Der Vertrag besagt: "Wenn Sie auf meinen Wert für mehrere Threads zugreifen, verspreche ich, dass jede Einstellung oder jeder Vorgang abgeschlossen wird, bevor ein anderer beginnt".

Aber Sie sagen, BOOL ist immer noch natürlich atomar, also ist dieser Vertrag nicht implizit?

Nein. Eine BOOL Variable ist natürlich atomar, aber wir sprechen von einer Eigenschaft . Eine -Eigenschaft wird möglicherweise nicht synthetisiert und hat möglicherweise nicht einmal eine einzige Variable, um sie zu sichern. Das ist eigentlich ziemlich üblich. Überlegen Sie:

%Vor%

Wer weiß was in deriveTheThingo !? Okay, das ist etwas kompliziert, aber der Punkt ist, dass EmptyThingo - unser Getter sieht nicht sehr atomar aus, oder? Was passiert, wenn ein Thread das Dingo ableitet und ein anderer Thread ruft, um herauszufinden, ob es leer ist?

Lange Rede, kurzer Sinn: Die Immobilie ist nicht atomar. Also sollten wir es so erklären.

Daher m ursprüngliche Antwort qualifiziert: Wenn Sie diese Eigenschaft selbst schreiben und @ synthesize verwenden, dann sind sie wahrscheinlich die gleichen, aber Sie sollten sie im Allgemeinen nicht gleich behandeln.

Als Faustregel gilt: Wenn Sie Multithread-Unterstützung nicht benötigen - was Sie normalerweise nicht tun, wenn Sie in UI-Code wie UIViewControllers arbeiten, dann deklarieren Sie einfach alles nichtatomisch.

    
Rhubarb 31.10.2012 11:04
quelle
8

In einer x-bit-Architektur (zB: 32bit, 64bit usw.) wird jeder Wert, der x oder weniger Bits ist, immer atomar gelesen oder geschrieben. Dies ist eine Eigenschaft jeder vernünftigen Hardware-Implementierung.

Die standardmäßige atomare Eigenschaft bedeutet, dass ein Eigenschaftswert immer gesetzt oder als Ganzes abgerufen wird, unabhängig davon, was andere Threads tun. Dies betrifft nur Eigenschaften, die die Anzahl der Bits der Architektur überschreiten. Nonatomic wird vom Compiler für jeden anderen Typ vollständig ignoriert.

Beispiel:

%Vor%
  • struct { int d; } ist bereits atomar, so dass die Accesoren keinen gegenseitigen Ausschluss benötigen.

  • struct { float x, float y} könnte sich in einem inkonsistenten Zustand befinden, wenn es nicht atomar wäre. Beispiel: Zwei Threads, die {1,2} und {3,4} setzen, könnten das Schreiben überlappen, und die Struktur könnte mit einem Wert aus jedem Satz enden: {1,4} .

  • Zeiger werden in einer einzigen Speicherposition gespeichert, erfordern jedoch mehrere Anweisungen für die Speicherverwaltung.

Atomare Eigenschaften tragen zur Thread-Sicherheit bei und vermeiden so Race-Bedingungen, die zu inkonsistenten Werten oder Missgeschicken bei der Speicherverwaltung führen. Dies allein garantiert keine Threadsicherheit, da es nicht mit anderen Problemen wie Deadlock, Verhungern, Sichtbarkeit usw. In Verbindung steht.

    
Jano 17.10.2012 15:58
quelle
2

Ja. nonatomic ist kein Speicherverwaltungs-Schlüsselwort, sondern hat mit Thread-Sicherheit zu tun. Außerdem sind Eigenschaften standardmäßig atomar (ohne sie explizit als nichtatomisch zu deklarieren). Daher ist ein Unterschied zwischen den beiden aufgeführten Deklarationen.

    
user529758 17.10.2012 15:55
quelle