KVC+KVO: Difference between revisions

From Medien Wiki
(created)
 
mNo edit summary
Line 1: Line 1:
Key-Value-Coding ist ein elementares und grundlegendes Design-Pattern von Cocoa:
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 "<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.:
<source lang="objc">
-(NSString*)name { return name; }
-(void)setName:(NSString*)newName {
    if(newName != name) {
        [name release];
        name = [newName copy];
    }
}
</source>
 
 
Der Einsatz von Properties erleichtert lediglich das Tippen, da hiermit die Accessoren beim Kompilieren automatisch erstellt werden:
<source lang="objc">
// MyFile.h
@property(nonatomic, copy) NSString* name;
// MyFile.m
@synthesize name;
</source>
 
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:
<source lang="objc">
// 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!!!
</source>
 
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.


<source lang="objc">
<source lang="objc">

Revision as of 12:55, 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 Accessoren dar, 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];
    }
}


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.

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.