Properties für Accessoren
Datenkapselung ist einer der wichtigsten Konzepte in der objektorientierten Programmierung. Um Datenkapselung zu gewährleisten, müssen Setter- und Getter-Methoden (Accessoren) für jede Instanzvariable geschrieben werden. Dies kann unter Umständen sehr zeitaufwendig sein. Die meisten Accessoren haben den gleichen Aufbau und unterscheiden sich lediglich durch die Instanzvariable. Da liegt die Idee nahe, diese Accessoren automatisch generieren zu lassen. Dieses vorgehen nennt man synthetisieren und wurde in Objektive-C 2.0 mit den sogenannten Properties eingeführt.
Propertys haben die allgemeine Syntax:
header
@property (attribut1, attribut2, attribut3, attribut4) datentyp variablenname;
implementation
@syntesize variablenname;
Hat man eine Instanzvariable synthetisiert kann wie folgt darauf zugegriffen werden:
Standard-Syntax
[Obj setVariablenname:wert]
printf(„Der wert lautet %i“, [Obj variablenname]);
Punkt-Syntax
Obj.variblenname = wert;
printf(„Der wert lautet %i“, Obj.variablenname);
Anmerkung:
Die Punkt-Syntax ist unabhängig von den Properties. Es ist möglich die Accessoren selbst zu schreiben (ohne Properties) und über die Punkt Syntax darauf zuzugreifen.
Die 4 Attribute beschreiben folgendes:
-Zugriffsart (readonly, readwrite)
-Setter-Semantik (assign, retain, copy
-Atomicity
-Setter- und Getter-Namen
Zugriffsart
Es gibt 2 Zugriffsarten. Entweder nur lesen (readonly) oder schreiben und lesen (readwrite).
Bei readwrite werden beide Accessoren synthetisiert (vom compiler geschrieben). Im Falle von read wird nur der Getter synthetisiert und somit ist nur ein lesender Zugriff möglich.
Setter-Semantik
Assign
Assign ist die standard Setter-Semantik. Falls man also nichts angibt wird vom Compiler automatisch assign genommen. Der neue Wert wird der Instanzvariable einfach nur zugewiesen, sonst nichts. Der Referenzcounter wird nicht erhöht. Dadurch ist eine ältere Erhöhung des Referenzcounters ausgeschlossen und er wird somit auch nicht erniedrigt. Dies hat zur Folge, dass die Empfänger -Klasse kein Besitzer des Objektes ist. Wird der Referenzcounter des Objekts von der Sender-Klasse erniedrigt, wird das Objekt gelöscht und ist somit auch nicht mehr für die Empfänger-Klasse erreichbar. Natürlich ist es auch umgekehrt möglich. Deswegen sollte man Propertys mit der assign-Semantik in der dealloc-Methode nicht releasen (den es wurde auch nirgends retained).
Beispiel (vom Compiler generierter Code für den Setter)
-(void)setVariablenname:(id)senderValue
{
instanceValue = senderValue;
}

Retain
Retain löst die Problematik der Assign-Semantik. Die Instanzvariable wird zunächst released, da es vielleicht schon auf ein Objekt zeigt. Danach wird der neue Wert zugewiesen und dann wird die Instanzvariable retained. Dies bedeutet nun dass die Empfänger-Klasse ein Besitzer des Objektes ist. Die Sender-Klasse kann das Objekt nun löschen und es ist für die Empfänger-Klasse immernoch erreichbar. Da man in der Retain-Semantik die Instanzvariable retained, muss sie in der dealloc-Methode auch released werden. Beide Klassen (Sender und Empfänger) zeigen nun auf dasselbe Objekt. Ändert eine Klasse das Objekt ist es auch für die andere geändert.
Beispiel (vom Compiler generierter Code für den Setter)
-(void)setVariablenname:(id)senderValue
if(instanceValue != senderValue)
{
[instanceValue release];
instanceValue = senderValue;
[instanceValue retain];
}
}

Copy
Copy erlaubt es einer Klasse der alleinige Beitzer eines Objektes zu werden. Das übergebene Objekt wird kopiert und danach erst zugewiesen. Dies hat den Vorteil dass Empfänger- und Sender-Klasse nicht mehr auf dasselbe Objekt zeigen und somit eine Änderung des Objekts der einen Klasse nicht für das Objekt der Anderen gilt. Die Klasse des übergebenen Objekts muss das NSCopying Protocol implementieren.
Beispiel (vom Compiler generierter Code für den Setter)
-(void)setVariablenname:(id)senderValue
{
if(instanceValue != senderValue)
{
[instanceValue release];
instanceValue = [senderValue copy];
}
}

Atomicity
Atomicity gewährleistet den sicheren Zugriff von mehreren Threads auf die Accessoren. Zu einer bestimmten Zeit darf nur ein Thread auf die Accessoren zugreifen. Möchte man dies vermeiden gibt man einfach das Attribut „nonatomic“ an. Mehr dazu auf friday.com
Setter- und Getter-Namen
Wie weiter oben beschrieben sind die Standard-Namen: „setVariablenname:“ (Setter) und „variablenname“ (Getter). Dies kann geändert werden. Um zum Beispiel im Falle von Boolean-Werten für den Getter einen Namen wie „isInitial“ zu erzeugen, kann man als Attribut „getter = isInitial“ angeben. Dadurch kann man auf den Boolwert wie folgt zugreifen:
[Object isInitial];
Object.isInitial;
Natürlich kann auch der Settername durch „setter=andererName“ geändert werden.
Außer man hat als Zugriffsart „read“ definiert, dann gibt es nähmlich einen Compilerfehler, da der Setter nicht existiert.
Quelle
developer.apple.com

English
Deutsch





















