Frage

Ich arbeite durch die "Key Value Coding" Kapitel in "Programmierung für Mac OS X". Ich habe eine Schnittstelle mit einem Schieberegler eingebaut und ein Etikett, beide gebunden an fido, ein int. Wenn ich die Eigenschaft für fido auf Read-only gesetzt, bewirkt, dass der Schieber bewegt noch das Etikett ändern Wert es ist. Ich hatte angenommen, dass ich für diese irgendeine Art von Fehler bekommen würde. Wenn die Eigenschaft nur lesbar ist, wie kommt es, dass der Schieber noch auf die Eigenschaft schreiben? Ich dachte, dass es hätte keine Setter erstellt und KVC nicht funktionieren würde. Danke.

Hier ist der Code verwende ich:

#import <Cocoa/Cocoa.h>

@interface AppController : NSObject
{
    int fido;
}

@property (readonly, assign) int fido;

@end

#import "AppController.h"

@implementation AppController

@synthesize fido;

- (id)init
{
    [super init];
    [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];
    NSNumber *n = [self valueForKey:@"fido"];
    NSLog(@"fido = %@", n);
    return self;
}
@end

alt text http://idisk.me.com/nevan/Public /Pictures/Skitch/Window-20091001-174352.png

War es hilfreich?

Lösung

AppController.h:

@interface AppController : NSObject
{
        int fido;
}

@property (readonly, assign) int fido;
@end

Import "AppController.h"

@implementation AppController
@synthesize fido;
...
@end

An diesem Punkt haben Sie erklärt, dass AppController eine -fido Methode hat, und Sie haben das Verfahren synthetisiert. Es gibt keine -setFido: Methode. Also, warum hat die folgende „Arbeit“?

- (id)init
{
        if (self=[super init]) {
            [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];
            NSNumber *n = [self valueForKey:@"fido"];
            NSLog(@"fido = %@", n);
        }
        return self;
}

(BTW: Ich reparierte Ihr -init das richtige Muster zu implementieren)

Das funktioniert, weil KVC ein heuristisches folgt setzen oder den Wert zu erhalten. Der Aufruf von -setValue:forKey: erster Looks für -setFoo:. Wenn nicht gefunden, es sieht dann für das Instanzvariable foo und setzt sie direkt an.

Beachten Sie, wenn Sie die Instanz-Variable fido _fido ändern, wird das Set arbeiten, aber die valueForKey 0 zurück, da sie die synthetisierte Methode aufruft (da ich auf 64-Bit bin synthetisiert die @synthesize eine fido Instanzvariable. verwirrend, ich weiß.).

Wenn Sie den Namen Ihres Ivar ändern sind bar und dann @synthesize foo=bar; verwenden, würde der Code zur Laufzeit fehlschlagen.

Sie werden sehen:

2009-10-01 08:59:58.081 dfkjdfkjfjkfd[24099:903] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppController 0x20000e700> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key fido.'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff85b055a4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff85c5a0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b5caf9 -[NSException raise] + 9
    3   Foundation                          0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
(
    0   CoreFoundation                      0x00007fff85b055a4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff85c5a0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b5caf9 -[NSException raise] + 9
    3   Foundation                          0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
    4   dfkjdfkjfjkfd                       0x0000000100000d96 -[AppController init] + 130

Andere Tipps

Nur-Lese-Eigenschaft bedeutet, dass Compiler nicht generieren Sie für diese Eigenschaft Setter. Es ist immer noch legal es über KVO / KVC zu schreiben.

Die Compiler-Direktiven @property und @synthesize ist nur ein Kurz Möglichkeit, um die Methoden zum Erstellen zu erhalten und die betreffenden Variable gesetzt.

Die Setter-Methode erstellt wird setFido: genannt, und die Getter-Methode wird nur genannt fido.

Wenn Sie nur lesbar angeben, glaube ich, dass Sie einfach den Compiler erzählt die Setter-Methode nicht zu schaffen, sondern nur den Getter. Es spielt stellt keine Art von Barriere im Weg die Variable durch andere Mittel zu setzen.

(Hoffe, ich habe all das richtig verstanden habe. Viel Glück!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top