2013-08-03 11 views
9

Ich versuche mich selbst objektiv-c mit dem großen Nerd Ranch-Buch zu lehren, es ist ein wirklich tolles Buch, aber bestimmte Aspekte verwirren mich.Objective-C setValue: forKey auf c primitive Typen

Das aktuelle Kapitel spricht über die Verwendung von setValue: forKey-Funktion, die ich verstehe, ist eine Methode in NSObject definiert. Das Buch sagt, dass man diese auf ac primitiven wie int oder float verwenden kann, und gibt dieses Beispiel

Ich habe eine benutzerdefinierte Klasse Appliance und es ist ein Integer-Instanz-Variable genannt Spannung genannt, die die Spannung der Speicher Strom Gerät ich initialisieren ein neues Gerät namens ein

appliance *a = [[appliance alloc]init]; 
[a setValue:[NSNumber numberWithInt:240] forKey:@"voltage"]; 

er richtet dann eine benutzerdefinierte Setter für Spannung und protokolliert die Spannung, wenn sein zu beweisen, nannte es funktioniert

-(void)setVoltage:int(x) { 
NSLog(@"setting voltage to %d",x); 
voltage =x; 
} 

Was verwirrend ist, dass NSNumber numberWithInt einen Zeiger auf ein NSNumber-Objekt zurückgibt, das auf dem Heap korrekt gespeichert ist? Wie also protokolliert er die in NSNumber gespeicherte Ganzzahl mit dem Token% d? Ich verstehe, dass würde eine ganze Zahl protokollieren, aber ist kein Objekt übergeben? Außerdem dachte ich, dass, da die Spannung als Integer und nicht als Zeiger auf etwas definiert war, sie die Adresse nicht auf einem Objekt in ihrem Speicher halten konnte? Oder zwingt NSNumber es, seine Speicheradresse zu halten, ohne dass tatsächlich Spannung als Zeiger deklariert wird?

Entschuldigung für die Verwirrung dieses Kapitels trat im Grunde meinen Hintern.

+3

Beachten Sie, dass Sie in normalen Programmierpraktiken normalerweise 'setValue: forKey:' oder 'valueForKey:' verwenden, um Werte für ein Objekt * festzulegen/abzurufen. Rufen Sie einfach den Setter/Getter direkt an. KVC existiert größtenteils, um Dinge wie Bindungen und andere Formen der Meta-Programmierung zu unterstützen. – bbum

Antwort

25

Die Konvertierung zwischen Objekten und Skalartypen wird automatisch von den Schlüsselwertcodierungsmethoden übernommen. Vom documentation:

Die Standardimplementierungen von valueForKey: und setValue:forKey: bieten Unterstützung für automatische Objekt Umwickeln der Nicht-Objektdaten Typen, beide Skalare und structs.

Sobald valueForKey: hat die spezifische Zugriffsmethode oder Instanzvariable bestimmt, die verwendet wird, um den Wert für die angegebenen Schlüssel zu liefern, untersucht sie den Rückgabetyp oder den Datentyp. Wenn der zurückgegebene Wert kein Objekt ist, wird ein NSNumber oder NSValue Objekt für diesen Wert erstellt und an seiner Stelle zurückgegeben.

In ähnlicher Weise bestimmt setValue:forKey: den Datentyp, der von der entsprechenden Accessor- oder Instanzvariablen für den angegebenen Schlüssel benötigt wird. Wenn der Datentyp kein Objekt ist, wird der Wert aus dem übergebenen Objekt mit der entsprechenden Methode -<type>Value extrahiert.

in Ihrem Fall So wird intValue automatisch auf den übergebenen NSNumber Objekt angewendet und die resultierende ganze Zahl ist setVoltage: geben.

4

Sie haben Recht, dass Sie eine NSNumber Instanz erstellen und diese übergeben. Aber du gibst es an setValue:forKey: weiter und es macht etwas Arbeit für dich.Es wird die passende Setter-Methode für voltage (setVoltage:) gefunden, der Datentyp überprüft und die Nummer in eine int unboxing vor dem Aufrufen der Setter.

Verwandte Themen