Nummer 1 unterscheidet sich von den beiden anderen dadurch, dass die MyOtherObject-Klasse vorwärts deklariert wird, um die vom Compiler und Linker gesehene Codemenge zu minimieren und möglicherweise auch Zirkelverweise zu vermeiden. Wenn Sie dies auf diese Weise tun, denken Sie daran, den #import in die .m-Datei einzufügen.
Indem Sie eine @ -Eigenschaft deklarieren (und @synthesize in der .m-Datei abgleichen), generieren Sie automatisch Zugriffsmethoden mit der von Ihnen angegebenen Speichersemantik. Die Faustregel für die meisten Objekte lautet Beibehalten, aber NSStrings sollte beispielsweise Kopieren verwenden. Während Singletons und Delegierte normalerweise Assign verwenden sollten. Handschriftliche Accessoren sind mühsam und fehleranfällig, so dass viele Tipp- und dumme Fehler vermieden werden.
Wenn Sie eine synthetisierte Eigenschaft deklarieren, können Sie eine Accessor-Methode mit der folgenden Punktnotation aufrufen:
self.otherObj = someOtherNewObject; // set it
MyOtherObject *thingee = self.otherObj; // get it
Anstelle der normalen Art der Nachrichtenübermittlung:
[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it
Hinter den Kulissen rufen Sie wirklich eine Methode auf, die so aussieht:
- (void) setOtherObj:(MyOtherObject *)anOtherObject {
if (otherObject == anOtherObject) {
return;
}
MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
otherObject = [anOtherObject retain]; // put the new value in
[oldOtherObject release]; // let go of the old object
} // set it
…oder dieses
- (MyOtherObject *) otherObject {
return otherObject;
} // get it
Totaler Schmerz im Hintern, richtig. Tun Sie das jetzt für jeden Ivar in der Klasse. Wenn Sie es nicht genau richtig machen, kommt es zu einem Speicherverlust. Am besten lassen Sie den Compiler die Arbeit machen.
Ich sehe, dass Nummer 1 keinen Ivar hat. Angenommen, dies ist kein Tippfehler, ist es in Ordnung, da die Direktiven @property / @synthesize hinter den Kulissen auch für Sie einen Ivar deklarieren. Ich glaube, das ist neu für Mac OS X - Snow Leopard und iOS4.
In Nummer 3 werden diese Accessoren nicht generiert, sodass Sie sie selbst schreiben müssen. Wenn Sie möchten, dass Ihre Accessor-Methoden Nebenwirkungen haben, führen Sie Ihren Standard-Tanz zur Speicherverwaltung wie oben gezeigt durch und führen dann innerhalb der Accessor-Methode die erforderlichen Nebenarbeiten aus. Wenn Sie eine Eigenschaft synthetisieren und eine eigene schreiben , hat Ihre Version Vorrang.
Habe ich alles abgedeckt?
setFoo:
undfoo
) haben, können Sie die Punktnotation verwenden.Früher hatten Sie Ivars, und wenn Sie eine andere Klasse einstellen oder lesen lassen wollten, mussten Sie einen Getter (dh
-(NSString *)foo)
einen Setter (dh-(void)setFoo:(NSString *)aFoo;
) definieren.Was Ihnen Eigenschaften geben, ist der Setter und Getter kostenlos (fast!) Zusammen mit einem Ivar. Wenn Sie jetzt eine Eigenschaft definieren, können Sie die Atomizität festlegen (möchten Sie beispielsweise mehrere Einstellungsaktionen von mehreren Threads zulassen) sowie die Semantik zuweisen / beibehalten / kopieren (dh sollte der Setter den neuen Wert kopieren) oder speichern Sie einfach den aktuellen Wert - wichtig, wenn eine andere Klasse versucht, Ihre Zeichenfolgeeigenschaft mit einer veränderlichen Zeichenfolge festzulegen, die später möglicherweise geändert wird.
Das
@synthesize
macht es. Viele Leute lassen den ivar-Namen gleich, aber Sie können ihn ändern, wenn Sie Ihre Synthesize-Anweisung schreiben (dh, Sie@synthesize foo=_foo;
erstellen einen ivar-Namen_foo
für die Eigenschaftfoo
. Wenn Sie diese Eigenschaft also lesen oder schreiben möchten und sie nicht verwendenself.foo
, werden Sie dies tun müssen verwenden_foo = ...
- es hilft Ihnen nur, direkte Verweise auf den Ivar zu finden, wenn Sie nur durch den Setter und Getter gehen wollten).Ab Xcode 4.6 müssen Sie die
@synthesize
Anweisung nicht mehr verwenden - der Compiler führt dies automatisch aus und stellt standardmäßig den Namen des ivar voran_
.quelle