Eine Eigenschaft ist ein abstrakteres Konzept. Eine Instanzvariable ist buchstäblich nur ein Speichersteckplatz, wie ein Steckplatz in einer Struktur. Normalerweise sollten andere Objekte niemals direkt darauf zugreifen. Eine Eigenschaft hingegen ist ein Attribut Ihres Objekts, auf das zugegriffen werden kann (es klingt vage und soll es auch sein). Normalerweise gibt eine Eigenschaft eine Instanzvariable zurück oder legt diese fest, kann jedoch Daten von mehreren oder gar keinen verwenden. Beispielsweise:
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(Hinweis: Der obige Code ist insofern fehlerhaft, als er davon ausgeht, dass der Name bereits vorhanden ist und mindestens zwei Komponenten enthält (z. B. "Bill Gates" und nicht nur "Gates"). Ich hatte das Gefühl, dass das Korrigieren dieser Annahmen den eigentlichen Sinn des Codes ausmachen würde weniger klar, deshalb weise ich hier nur darauf hin, damit niemand diese Fehler unschuldig wiederholt.)
Eine Eigenschaft ist eine benutzerfreundliche Methode zum Implementieren eines Getters / Setters für einen bestimmten Wert mit zusätzlichen nützlichen Funktionen und Syntax. Eine Eigenschaft kann durch eine Instanzvariable gesichert werden, Sie können jedoch auch den Getter / Setter definieren, um etwas Dynamischeres zu tun. Sie können beispielsweise eine LowerCase-Eigenschaft für eine Zeichenfolge definieren, die das Ergebnis dynamisch erstellt, anstatt den Wert eines Elements zurückzugeben Variable.
Hier ist ein Beispiel:
Die
@property
Zeile definiert eine Eigenschaft namenspropertyName
typeNSString *
. Dies kann mit der folgenden Syntax abgerufen / festgelegt werden:Wenn Sie zuweisen oder daraus lesen,
myObject.propertyName
rufen Sie wirklich Setter / Getter-Methoden für das Objekt auf.Die
@synthesize
Zeile weist den Compiler an, diese Getter / Setter für Sie zu generieren, indem die Mitgliedsvariable mit demselben Namen der Eigenschaft zum Speichern des Werts verwendet wird (oderotherVarName
wenn Sie die Syntax in Kommentaren verwenden).Zusammen mit können
@synthesize
Sie dennoch einen der Getter / Setter überschreiben, indem Sie Ihren eigenen definieren. Die Namenskonvention für diese Methoden giltsetPropertyName:
für den Setter undpropertyName
(odergetPropertyName
nicht Standard) für den Getter. Der andere wird weiterhin für Sie generiert.In Ihrer
@property
Zeile können Sie eine Reihe von Attributen in Parens für die Eigenschaft definieren, die Dinge wie Thread-Sicherheit und Speicherverwaltung automatisieren können. Standardmäßig ist eine Eigenschaft atomar, was bedeutet, dass der Compiler@synthesiz
get get / set-Aufrufe mit geeigneten Sperren umschließt, um Parallelitätsprobleme zu vermeiden. Sie können dasnonatomic
Attribut angeben , um dies zu deaktivieren (z. B. auf dem iPhone, für das Sie die meisten Eigenschaften standardmäßig verwenden möchtennonatomic
).Es gibt 3 Attributwerte, die die Speicherverwaltung für alle
@synthesized
Setter steuern . Die ersteretain
wird automatischrelease
an alte Werte der Eigenschaft undretain
an die neuen Werte gesendet. Das ist sehr nützlich.Die zweite
copy
Möglichkeit besteht darin, eine Kopie aller übergebenen Werte zu erstellen, anstatt sie beizubehalten. Es wirdcopy
empfohlen, NSString zu verwenden, da ein Anrufer einen NSMutableString übergeben und unter Ihnen ändern kann.copy
erstellt eine neue Kopie der Eingabe, auf die nur Sie Zugriff haben.Das dritte ist
assign
das Zuweisen eines geraden Zeigers, ohne das alte oder neue Objekt zum Zurückhalten / Freigeben aufzurufen.Zuletzt können Sie das
readonly
Attribut auch verwenden , um den Setter für die Eigenschaft zu deaktivieren.quelle
Ich verwende Eigenschaften für den Schnittstellenteil - wo die Objektschnittstellen mit anderen Objekten und Instanzvariablen Dinge sind, die Sie in Ihrer Klasse benötigen - niemand außer Ihnen soll diese sehen und bearbeiten.
quelle
Standardmäßig wird eine readwrite-Eigenschaft von einer Instanzvariablen unterstützt, die vom Compiler automatisch wieder synthetisiert wird.
Eine Instanzvariable ist eine Variable, die existiert und ihren Wert für die Lebensdauer des Objekts behält. Der für Instanzvariablen verwendete Speicher wird beim ersten Erstellen des Objekts (durch Zuweisung) zugewiesen und beim Freigeben des Objekts freigegeben.
Sofern Sie nichts anderes angeben, hat die synthetisierte Instanzvariable denselben Namen wie die Eigenschaft, jedoch mit einem Unterstrichpräfix. Für eine Eigenschaft namens firstName heißt die synthetisierte Instanzvariable beispielsweise _firstName.
quelle
Früher nutzten Benutzer Eigenschaften öffentlich und ivars für den privaten Gebrauch. Seit einigen Jahren können Sie jedoch auch Eigenschaften definieren
@implementation
, um sie privat zu nutzen. Aber ich würde immer noch ivars verwenden, wenn es möglich ist, da weniger Buchstaben eingegeben werden müssen und es laut diesem Artikel schneller läuft . Dies ist sinnvoll, da Eigenschaften "schwer" sein sollen: Auf sie soll entweder von generierten Getter / Setter oder von manuell geschriebenen Getter zugegriffen werden.In neueren Codes von Apple werden Ivars jedoch nicht mehr verwendet. Ich denke , weil es mehr wie
objc
nichtC/C++
, und es ist einfacher , Eigenschaften zu verwenden , mitassign
,nullable
etc.quelle
@implementation
Ähnlichkeiten mit Swift zeigen möchte. Trotzdem bevorzuge ich es auch, Variablen zu sichern, um keinen virtuellen Funktionsaufruf zu verschwenden, um ein einfaches Feld meiner eigenen Klasse nachzuschlagen (und das passiert, wenn auf die Eigenschaft zugegriffen wird).