Frage Gibt es einen Unterschied zwischen einer Instanzvariable und einer Eigenschaft in Objective-c?


Gibt es einen Unterschied zwischen einer Instanzvariable und einer Eigenschaft in Objective-c?

Da bin ich mir nicht sicher. Ich denke, dass eine "Eigenschaft" eine Instanzvariable ist, die Zugriffsmethoden hat, aber ich könnte falsch denken.


76
2018-05-09 16:53


Ursprung


Antworten:


Eine Eigenschaft ist ein abstrakteres Konzept. Eine Instanzvariable ist buchstäblich nur ein Speicher-Slot, wie ein Slot in einer Struktur. Normalerweise sollen andere Objekte niemals direkt auf sie zugreifen. Eine Eigenschaft hingegen ist ein Attribut Ihres Objekts, auf das zugegriffen werden kann (es klingt vage und sollte es auch). Normalerweise gibt eine Eigenschaft eine Instanzvariable zurück oder legt sie fest, aber sie kann Daten aus mehreren oder gar keinen Daten 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

(Anmerkung: Der obige Code ist insofern fehlerhaft, als er davon ausgeht, dass der Name bereits existiert und mindestens zwei Komponenten hat (zB "Bill Gates" und nicht nur "Gates"). Ich glaubte, dass die Festlegung dieser Annahmen den eigentlichen Punkt des Codes ausmachen würde weniger klar, also zeige ich es hier nur so, dass niemand diese Fehler unschuldig wiederholt.)


81
2018-05-09 17:29



Eine Eigenschaft ist eine benutzerfreundliche Möglichkeit, einen Getter / Setter für einen bestimmten Wert mit zusätzlichen nützlichen Funktionen und einer Syntax zu implementieren. Eine Eigenschaft kann durch eine Instanzvariable unterstützt werden, aber Sie können auch festlegen, dass der Getter / Setter etwas dynamischer vorgeht, z. Sie könnten eine lowCase-Eigenschaft für eine Zeichenfolge definieren, die das Ergebnis dynamisch erstellt, anstatt den Wert einiger Elementvariablen zurückzugeben.

Hier ist ein Beispiel:

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;

Das @property Zeile definiert eine Eigenschaft namens propertyName vom Typ NSString *. Dies kann mit folgender Syntax get / gesetzt werden:

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);

Wenn Sie zuweisen oder von lesen myObject.propertyName Sie rufen wirklich Setter / Getter-Methoden für das Objekt auf.

Das @synthesize Zeile weist den Compiler an, diese Getter / Setter für Sie zu generieren, indem Sie die Membervariable mit demselben Namen der Eigenschaft verwenden, um den Wert zu speichern (oder otherVarName wenn Sie die Syntax in Kommentaren verwenden).

Zusammen mit @synthesize Sie können einen der Getter / Setter trotzdem überschreiben, indem Sie Ihren eigenen definieren. Die Namenskonvention für diese Methoden ist setPropertyName: für den Setzer und propertyName (oder getPropertyName, nicht Standard) für den Getter. Der andere wird immer noch für dich generiert.

In deinem @property Zeile Sie können eine Anzahl 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 umbrochen wird @synthesized Get / Set-Aufrufe mit entsprechenden Sperren, um Nebenläufigkeitsprobleme zu verhindern. Sie können das angeben nonatomic Attribut, um dies zu deaktivieren (zum Beispiel auf dem iPhone, auf das die meisten Eigenschaften eingestellt werden sollen) nonatomic).

Es gibt 3 Attributwerte, die die Speicherverwaltung für alle steuern @synthesized Setter. Das erste ist retain welches automatisch sendet release zu alten Werten der Immobilie, und retain zu den neuen Werten. Dies ist sehr nützlich.

Das zweite ist copy Dadurch wird eine Kopie aller übergebenen Werte erstellt, anstatt sie beizubehalten. Es ist eine gute Übung zu verwenden copyfür NSString, da ein Aufrufer einen NSMutableString übergeben und unter Ihnen ändern kann. copy erstellt eine neue Kopie der Eingabe, auf die nur Sie Zugriff haben.

Der dritte ist assign was einem geraden Zeiger zugewiesen wird, ohne auf das alte oder neue Objekt zurückzugreifen / freizugeben.

Zuletzt können Sie auch die readonly Attribut, um den Setter für die Eigenschaft zu deaktivieren.


30
2018-05-09 17:53



Ich verwende Eigenschaften für den Schnittstellenteil - wo das Objekt mit anderen Objekten verbunden ist und Instanzvariablen sind Zeug, das Sie in Ihrer Klasse brauchen - niemand außer Ihnen soll diese sehen und manipulieren.


6
2018-06-15 13:54



Standardmäßig wird eine readwrite-Eigenschaft von einer Instanzvariable unterstützt, die wiederum automatisch vom Compiler synthetisiert wird.

Eine Instanzvariable ist eine Variable, die existiert und ihren Wert für die Lebensdauer des Objekts enthält. Der für Instanzvariablen verwendete Speicher wird beim Erstellen des Objekts (über Alloc) zugewiesen und bei der Zuweisung des Objekts freigegeben.

Sofern Sie nichts anderes angeben, hat die synthetisierte Instanzvariable den gleichen Namen wie die Eigenschaft, jedoch mit einem Unterstrichpräfix. Bei einer Eigenschaft mit dem Namen firstName heißt die synthetisierte Instanzvariable beispielsweise _firstName.


3
2018-05-28 11:13



Zuvor verwenden Personen Eigenschaften öffentlich und ivars für die private Nutzung, aber seit einigen Jahren können Sie auch Eigenschaften in definieren @implementation um sie privat zu benutzen. Aber ich würde immer noch Ivars verwenden, wenn es möglich ist, da weniger Buchstaben zu tippen sind, und es läuft schneller nach Dieser Artikel. Es macht Sinn, da Eigenschaften "schwer" sein sollen: Sie sollen entweder von generierten Getter / Setter oder von Hand geschrieben werden.

In den aktuellen Codes von Apple werden jedoch keine Ivars mehr verwendet. Ich schätze, weil es eher so ist objc eher, als C/C++Außerdem ist es einfacher, Eigenschaften mit zu verwenden assign, nullable, etc.


1
2018-06-07 13:15