2013-01-01 9 views
7

Mögliche Duplizieren:
How does an underscore in front of a variable in a cocoa objective-c class work?self.variableName vs. _variableName vs. @sysnthesize Variablen


Hinweis: Für die Leute zu graben, um dies versuchen zu verstehen, ich herausgefunden, die Quelle meiner Verwirrung. Im .h, ich hatte:

... 
@interface myClass : parentClass { 
className *variableName: 
} 

@property (strong, nonatomic) className *variableName; 
... 

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

... 
@interface myClass : parentClass { 
className *_variableName: 
} 

@property (strong, nonatomic) className *variableName; 
... 

Dann wird in der Klasse .m, self.variableName und _variableName gleichwertig sind


In brandneue, Xcode 4.5+, mit ARC, Targeting iOS 5.0 + Projekt, gibt es einen deutlichen Vorteil (Laufzeit-Effizienz, Geschwindigkeit, etc.) zu _variableName über self.variableName gegenüber dem alten Stil @synthesize variableName zu verwenden?

Mein Verständnis ist, dass Xcode 4.5+ einen Standard-Zugriffs schaffen _variableName, die self.variableName gleichwertig ist und die einzigen Gründe, nicht zu verwenden @synthesize variableName Verwirrung zwischen Ivars zu vermeiden ist, und übergebenen Variablen, richtig?

Für mich scheint nur die Verwendung self.variableName Zugriff auf eine iVar am einfachsten und klar, welche Variable Sie suchen. Anders als die Eingabe _ vs. self., gibt es einen Vorteil, _variableName zu verwenden?

+1

Und hier ist eine andere 16: http://stackoverflow.com/q/5582448/ http://stackoverflow.com/q/6049269/ http://stackoverflow.com/q/2371489/ http://stackoverflow.com/q/7174277/ http://stackoverflow.com/q/5659156 http://stackoverflow.com/q/837559/ http://stackoverflow.com/q/6146244/ http: //Paketüberfluss.com/q/10651535/ http://Stackoverflow.com/q/6124109/ http://StackOverflow.com/Q/8145373/ http://StackOverflow.com/Q/3521254/ http: // stackoverflow.com/q/6064283/ http://stackoverflow.com/q/9696359/ http://stackoverflow.com/q/5521499/ http://stackoverflow.com/q/5466496/ http: //stackoverflow.com/q/2114587/ –

+0

Mein schlechtes. Ich denke nicht daran, nach 'unterstrichen' zu suchen. Das heißt, einige der möglichen Überprüfungen werden stichprobenartig überprüft. Ich habe keine/newbie-proof-Erwähnung der möglichen Probleme mit Schlüsselwertbeobachtung, Bindungen und threadsicherem Zugriff (atomar) gesehen, wenn _variableName vs. self verwendet wird .Variablennamen. Ein (4088801) hat ein potenzielles Problem erwähnt, wenn das Objekt, auf das in _variableName verwiesen wird, freigegeben ist und stattdessen die Verwendung von self.variableName empfohlen wird. –

+0

Wenn Sie ein bestimmtes Problem sehen, das in einer der vielen Instanzen der allgemeinen Frage übersehen wird, sollten Sie sich frei dazu äußern. Es hat jedoch wenig Wert, dass diese Informationen zufällig in einer anderen Kopie vergraben werden. –

Antwort

15

Mein Verständnis ist, dass Xcode 4.5+ wird eine Standard-Accessor „_variableName“ erstellen, die auf self.variableName und die einzigen Gründe, entspricht nicht verwenden „@synthesize Variablenname“ ist eine Verwechslung zwischen Ivars zu vermeiden und weitergegeben-in Variablen, richtig?

In diesem Fall _variableName ist nicht die Accessor, es ist ein Ivar, der automatisch vom Compiler erzeugt wird und in dem automatisch @synthesized Getter und Setter verwendet. Im Allgemeinen wird es als am besten angesehen, Zugriffsmethoden zu verwenden, wann immer dies möglich ist (d. H.), so dass Dinge wie Schlüsselwertbeobachtung und Bindungen für diese Eigenschaft funktionieren.

Wenn Sie direkt auf einen ivar zugreifen, wird über 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. Mit Punktnotation (self.variableName) ruft die Accessormethoden diese Eigenschaft zu setzen oder zu erhalten und kann auf dem Weg, wie eine Reihe von verschiedenen Dingen tun:

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

2) Schlüsselwert Benachrichtigungen: Die Standardsetzer für Eigenschaften nennen -willChangeValueForKey: und -didChangeValueForKey:, welche Benachrichtigungen sendet, wenn die Eigenschaft geändert wird. Dies ist notwendig, damit alles ordnungsgemäß aktualisiert werden kann, wenn Bindungen verwendet werden, und für jede andere Schlüsselwertbeobachtung.

3) Benutzerdefiniertes Accessor-Verhalten: Wenn Sie Ihre eigenen Setter und Getter schreiben, irgendwelche benutzerdefinierten Sachen, die Sie in denen implementieren.

Technisch gesehen ist der direkte Zugriff auf den ivar schneller als die Verwendung von Accessoren, aber es gibt nur sehr wenige Situationen, in denen ein signifikanter Leistungsunterschied auftritt und wahrscheinlich eine vorzeitige Optimierung vorliegt. Selbst wenn Sie nicht das Gefühl haben, dass Sie die oben genannten Vorteile sofort nutzen würden, 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 direkt auf Ivars zugreifen und Ihre Klasse in Kategorien oder Unterklassen umgestalten, wird es unordentlich, weil Sie den ivar normalerweise als @protected Variable deklarieren müssen. Sie müssten dies nicht tun, wenn Sie die Accessoren verwenden.

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

5

In der neuesten Xcode @synthesize ist optional. In der Standardeinstellung ist @synthesize Weglassen das gleiche wie das Schreiben

@synthesize someName = _someName; 

Der einzige Grund, @synthesize zu umbenennen zu verwenden ist die Instanz-Variable den Wert der Immobilie zu speichern erstellt, zum Beispiel

@synthesize someName = someSpecialName; 

Wenn Sie verwenden self.variableName, um auf eine Variable zuzugreifen. Sie durchlaufen 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 nonatomic in der Eigenschaftsdeklaration nicht angeben). In solchen Fällen wird der Zugriff über 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.

+0

Um pedantisch zu sein, basierend auf Ihrer Antwort und @eyebrowsoffire, _variableName, könnte schneller sein, aber self.variableName ist sicherer? –

+0

@RayatERISCorp "Safer" ist in diesem Kontext unterdefiniert, aber wenn Sie eine Eigenschaft in einer synchronisierten Weise verwenden möchten (d. H. Es ist "atomar"), lautet die Antwort ja, es ist sicherer. Tatsächlich funktioniert der andere Weg (d. H. Direkt für "_variableName") einfach nicht ohne zusätzliches Sperren. – dasblinkenlight

+0

Verstanden. Mit "sicherer" meine ich "weniger wahrscheinlich, dass ein unerwarteter Fehler in meinem Code ausgelöst wird, der mich länger als ich hätte debuggen lassen, da die Verwendung von _variableName nicht automatisch eine Aktion auslöst, die self.variableName ausführt." –

Verwandte Themen