KVC+KVO: Difference between revisions

From Medien Wiki
mNo edit summary
Line 4: Line 4:
Im Prinzip ist damit ein System von Accessoren gemeint. Am Beispiel wird das einfach deutlich. Nehmen wir an, eine Klasse hat eine iVar (Instanzvariable) und Property "<tt>NSString* myName</tt>":
Im Prinzip ist damit ein System von Accessoren gemeint. Am Beispiel wird das einfach deutlich. Nehmen wir an, eine Klasse hat eine iVar (Instanzvariable) und Property "<tt>NSString* myName</tt>":


In Cocoa wird üblicherweise außerhalb der Klasse niemals direkt auf eine Instanzvariable zugegriffen. Jede Klasse stellt hierfür Accessoren dar, also jeweils eine Getter- und eine Setter-Methode, z.B.:
In Cocoa wird üblicherweise außerhalb der Klasse niemals direkt auf eine Instanzvariable zugegriffen. Jede Klasse stellt hierfür sogenannte Accessoren zur Verfügung, also jeweils eine Getter- und eine Setter-Methode, z.B.:
<source lang="objc">
<source lang="objc">
-(NSString*)name { return name; }
-(NSString*)name { return name; }
Line 15: Line 15:
</source>
</source>


== @Properties = Accessors ==


Der Einsatz von Properties erleichtert lediglich das Tippen, da hiermit die Accessoren beim Kompilieren automatisch erstellt werden:
Der Einsatz von Properties erleichtert lediglich das Tippen, da hiermit die Accessoren beim Kompilieren automatisch erstellt werden:
Line 26: Line 27:
Durch @synthesize werden also die beiden o.g. Methoden generiert und dabei auf das Memory Management Rücksicht genommen.
Durch @synthesize werden also die beiden o.g. Methoden generiert und dabei auf das Memory Management Rücksicht genommen.


Gibt es diese Accessoren können die Werte wie folgt gelesen/gesetzt werden. Jede dieser Methoden (außer die letzte) ist gültig und macht exakt das Gleiche:
== Using Accessors ==
Gibt es diese Accessoren, können die Werte wie folgt gelesen/gesetzt werden. Jede dieser Methoden (außer die letzte) ist gültig und macht exakt das Gleiche:
<source lang="objc">
<source lang="objc">
// getter
// getter
Line 43: Line 45:


Man beachte, dass die mit "ACHTUNG" versehenen Zeilen nicht auf die Getter/Setter, sondern direkt auf die Instanzvariablen zugreifen. Damit wird u.a. auch das Memory Management (retain/release-Zyklen) umgangen, was natürlich schlecht ist ;-)
Man beachte, dass die mit "ACHTUNG" versehenen Zeilen nicht auf die Getter/Setter, sondern direkt auf die Instanzvariablen zugreifen. Damit wird u.a. auch das Memory Management (retain/release-Zyklen) umgangen, was natürlich schlecht ist ;-)


== Key/Value ==
== Key/Value ==

Revision as of 12:59, 7 March 2010

Key-Value-Coding ist ein elementares und grundlegendes Design-Pattern von Cocoa.

Accessors

Im Prinzip ist damit ein System von Accessoren gemeint. Am Beispiel wird das einfach deutlich. Nehmen wir an, eine Klasse hat eine iVar (Instanzvariable) und Property "NSString* myName":

In Cocoa wird üblicherweise außerhalb der Klasse niemals direkt auf eine Instanzvariable zugegriffen. Jede Klasse stellt hierfür sogenannte Accessoren zur Verfügung, also jeweils eine Getter- und eine Setter-Methode, z.B.:

-(NSString*)name { return name; }
-(void)setName:(NSString*)newName {
    if(newName != name) {
        [name release];
        name = [newName copy];
    }
}

@Properties = Accessors

Der Einsatz von Properties erleichtert lediglich das Tippen, da hiermit die Accessoren beim Kompilieren automatisch erstellt werden:

// MyFile.h
@property(nonatomic, copy) NSString* name;
// MyFile.m
@synthesize name;

Durch @synthesize werden also die beiden o.g. Methoden generiert und dabei auf das Memory Management Rücksicht genommen.

Using Accessors

Gibt es diese Accessoren, können die Werte wie folgt gelesen/gesetzt werden. Jede dieser Methoden (außer die letzte) ist gültig und macht exakt das Gleiche:

// getter
NSString *myString;
myString = [self name];
myString = [self valueForKey:@"name"];
myString = self.name;
myString = name; // ACHTUNG: hier wird direkt auf die iVar und nicht auf den Getter zugegriffen!!!

// setter
[self setName:@"Test"];
[self setValue:@"Test" forKey:@"name"];
self.name = @"Test";
name = @"Test"; // ACHTUNG: hier wird direkt auf die iVar und nicht auf den Setter zugegriffen!!!

Man beachte, dass die mit "ACHTUNG" versehenen Zeilen nicht auf die Getter/Setter, sondern direkt auf die Instanzvariablen zugreifen. Damit wird u.a. auch das Memory Management (retain/release-Zyklen) umgangen, was natürlich schlecht ist ;-)

Key/Value

Key-Value-Coding meint also ganz allgemein, das Zur-Verfügung-Stellen von Accessoren für Properties. Anders ausgedrückt, hat die Klasse verschiedene Eigenschaften ("Properties"), auf deren Werte ("Values") man mit Schlüsselwörtern ("Keys") zugreifen kann. Oder einfacher: jede Property kann mit einem valueForKey: und setValue:forKey: Selektor adressiert werden, ohne dass man die Klasse, mit der man kommuniziert, importieren muss.

// ohne key-value coding:
NSString* myString = [myObject name];
[myObject setName:@"Hallo Welt"];

// mit key-value coding:
NSString* myString = [myObject valueForKey:@"name"];
[myObject setValue:@"Hallo Welt" forKey:@"name"];

// collections benutzen Key-Value-Coding
NSNumber* myNumber = [myDict valueForKey:@"myNumber"];
[myDict setValue:[NSNumber numberWithInt:5] forKey:@"myNumber"];


Vorteile von Key-Value-Coding

  • Keine benannten Selektoren (nur valueForKey: und setValue:forKey:)
  • Sämtliche Cocoa-Collections (NSArray, NSDictionary...) benutzen KVC
  • Bindings (nicht verfügbar in iPhone OS <= 3.0) funktionieren mit KVC
  • Ideal für dynamisch synthetisierte Methoden


Links



Diese Seite ist Teil des Werkmoduls iOS Development von Michael Markert für Interface Design / Fakultät Medien an der Bauhaus-Universität Weimar.