self.variableName vs. _variableName vs. @sysnthesize variableName [duplizieren]

7

Hinweis: Für die Leute, die herumkramen und versuchen, das zu verstehen, habe ich die Ursache meiner Verwirrung herausgefunden. In der .h hatte ich:

%Vor%

Dies führt dazu, dass self.variableName und _variableName zwei verschiedene Variablen in der .m sind. Was ich brauchte, war:

%Vor%

Dann sind in der Klasse ".m" self.variableName und _variableName äquivalent

In brandneuer Version von Xcode 4.5+ mit ARC, das auf ein Projekt mit iOS 5.0+ abzielt, gibt es einen deutlichen Vorteil (Laufzeit-Effizienz, Geschwindigkeit usw.) für die Verwendung von _variableName gegenüber self.variableName gegenüber dem alten Stil @synthesize variableName ?

Nach meinem Verständnis wird Xcode 4.5+ einen Standardaccessor _variableName erstellen, der äquivalent zu self.variableName ist und die einzige Ursache dafür, dass @synthesize variableName nicht verwendet wird, ist die Vermeidung von Verwechslungen zwischen iVars und übergebenen Variablen, richtig?

Für mich ist die Verwendung von self.variableName für den Zugriff auf einen iVar am einfachsten und klar, nach welcher Variablen Sie suchen. Außer der Eingabe von _ vs. self. , gibt es einen Vorteil bei der Verwendung von _variableName ?

    
RayInNoIL 01.01.2013, 17:46
quelle

2 Antworten

16
  

Nach meinem Verständnis wird Xcode 4.5+ einen Standardaccessor "_variableName" erstellen, der äquivalent zu "self.variableName" ist und der einzige Grund, "@synthesize variableName" nicht zu verwenden, ist die Vermeidung von Verwechslungen zwischen iVars und übergebenen Variablen ?

In diesem Fall ist _variableName nicht der Accessor, sondern ein Ivar, der automatisch vom Compiler generiert und in den @ synthesized Setter und Getter verwendet wird. Im Allgemeinen wird die Verwendung von Zugriffsmethoden nach Möglichkeit als am besten angesehen (d. H.% Co_de%), so dass Dinge wie Schlüsselwertbeobachtung und Bindungen für diese Eigenschaft funktionieren.

Wenn Sie direkt auf einen ivar zugreifen, wird über den direkten Speicherzugriff auf dieselbe Weise zugegriffen wie auf Daten in einer Struktur. Es nimmt einfach den Zeiger für das Objekt, das den ivar besitzt, verschiebt die Speicheradresse und versucht, in den Speicher an dieser Stelle zu lesen oder zu schreiben. Die Verwendung der Punktnotation ( self.variableName ) ruft die Zugriffsmethoden auf, um diese Eigenschaft festzulegen oder abzurufen, und kann eine Reihe verschiedener Dinge auf dem Weg erledigen, wie zum Beispiel:

1) Sperren : Wenn die Eigenschaft in mehreren Threads verwendet wird und eine self.variableName -Eigenschaft ist, wird die Laufzeit automatisch gesperrt, um sicherzustellen, dass auf die Eigenschaft nicht zugegriffen wird gleichzeitig von mehreren Threads. Wenn Ihr Objekt nicht für mehrere Threads verwendet werden soll, können Sie den atomic -Hinweis in Ihrer Property-Deklaration angeben, sodass die synthetisierten Accessoren das Sperren überspringen.

2) Schlüsselwertbenachrichtigungen : Die Standardeinstellungen für Eigenschaften rufen nonatomic und -willChangeValueForKey: auf, wodurch Benachrichtigungen gesendet werden, wenn die Eigenschaft geändert wird. Dies ist notwendig, damit alles ordnungsgemäß aktualisiert wird, wenn Bindungen verwendet werden, und für jede andere Schlüsselwertbeobachtung.

3) Benutzerdefiniertes Accessor-Verhalten : Wenn Sie Ihre eigenen Setter und Getter schreiben, werden alle benutzerdefinierten Elemente in diesen implementiert.

Technisch gesehen ist der direkte Zugriff auf den ivar schneller als die Verwendung von Accessoren, aber es gibt nur sehr wenige Situationen, in denen dies zu signifikanten Leistungsunterschieden führt und wahrscheinlich eine vorzeitige Optimierung wäre. Selbst wenn Sie nicht das Gefühl haben, die oben genannten Vorteile sofort zu nutzen, ist es wahrscheinlich besser, die Accessoren trotzdem zu verwenden, damit Sie nicht jedes Mal, wenn Sie sich später entscheiden, etwas von dieser Funktionalität benötigen auf diese Variable zuzugreifen (und möglicherweise unerwartete neue Fehler in dem Prozess zu erzeugen).

Wenn Sie außerdem direkt auf Ivars zugreifen und Ihre Klasse in Kategorien oder Unterklassen umgestalten, wird es unordentlich, weil Sie den ivar normalerweise als -didChangeValueForKey: -Variable deklarieren müssen. Sie müssten dies nicht tun, wenn Sie die Accessoren verwenden.

Im Allgemeinen versuche ich nur direkt auf die Ivars in @protected , init und dem Accessor der Eigenschaft zuzugreifen. Viele Ingenieure gehen nach dieser Faustregel, weil manchmal die benutzerdefinierten Dinge, die in Accessoren vorkommen, zu unerwartetem Verhalten führen können, während das Objekt dealloc 'ing oder init ' ing ist. Zum Beispiel, wenn irgendetwas in den Accessoren etwas zu dealloc oder retain Ihr Objekt verursacht oder sogar eine schwache Nullreferenz darauf bildet, wird es einen Absturz verursachen, wenn es in release verwendet wird.

    
eyebrowsoffire 01.01.2013, 18:33
quelle
5

Im letzten Xcode ist @synthesize optional. Standardmäßig ist @synthesize gleich wie das Schreiben von

%Vor%

Der einzige Grund für die Verwendung von @synthesize ist die Umbenennung der Instanzvariablen, die zum Speichern des Werts der Eigenschaft erstellt wurde, z. B.

%Vor%

Wenn Sie mit self.variableName auf eine Variable zugreifen, durchlaufen Sie eine Eigenschaft, bei der es sich um eine kurze Methode handelt, die auf die Instanzvariable für Sie zugreift. Obwohl der Methodenversand sehr schnell ist, kann er zusätzliche Dienste für Sie ausführen, z. B. den Zugriff auf die Variable synchronisieren (dies ist der Fall, wenn Sie atomic angeben oder in der Eigenschaftsdeklaration nonatomic nicht angeben). In solchen Fällen wird der Zugriff durch self.variableName etwas langsamer sein. Wenn dies in einer engen Schleife geschieht, könnte dies möglicherweise einen Unterschied machen. Aus diesem Grund möchten Sie manchmal direkt auf die zugrunde liegende Instanzvariable zugreifen, indem Sie _variableName verwenden.

    
dasblinkenlight 01.01.2013 17:56
quelle

Tags und Links