Pregunta

Estoy trabajando a través del capítulo "Valor de clave de codificación" en "Programación para Mac OS X". He construido una interfaz con un control deslizante y una etiqueta, tanto ligada a Fido, un int. Si establece la propiedad de sólo lectura a Fido, moviendo el deslizador sigue causando la etiqueta para cambiar su valor. Había supuesto que me gustaría conseguir algún tipo de error para esto. Si la propiedad es de sólo lectura, ¿cómo es que el cursor puede escribir todavía a la propiedad? Pensé que no tendría ningún set creados, y KVC no funcionaría. Gracias.

Aquí está el código que estoy usando:

#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

¿Fue útil?

Solución

AppController.h:

@interface AppController : NSObject
{
        int fido;
}

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

importación "AppController.h"

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

En este punto, usted ha declarado que AppController tiene un método -fido y ha sintetizado ese método. No existe un método -setFido:. Así que, ¿por qué hace lo siguiente "trabajo"?

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

(Por cierto: me fijo su -init para implementar el patrón correcto)

Esto funciona porque KVC sigue un heurística para establecer u obtener el valor. La llamada a -setValue:forKey: primero busca -setFoo:. Si no lo encuentra, a continuación, busca la instancia foo variable y fija directamente.

Tenga en cuenta que si cambia la variable de instancia fido a _fido, el conjunto va a funcionar, pero el valueForKey devolverá 0, ya que llama al método sintetizado (ya que estoy en 64 bits, el @synthesize sintetiza una variable de instancia fido. confuso, lo sé.).

Si se va a cambiar el nombre de su Ivar a bar y luego usar @synthesize foo=bar;, el código podría fallar en tiempo de ejecución.

Usted verá:

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

Otros consejos

Tener la propiedad de sólo lectura significa que el compilador no generará que setter para esa propiedad. Es todavía legal para escribir en él a través de MVA / KVC.

El @property directivas del compilador y @synthesize son simplemente formas de taquigrafía para crear los métodos para obtener y establecer la variable en cuestión.

El método setter creado se denomina setFido:, y el método getter se acaba de nombrar fido.

Cuando se especifica sólo lectura, creo que simplemente le dice al compilador que no crear el método de selección, pero sólo el captador. Que no pone ningún tipo de barrera en la forma de establecer la variable por otros medios.

(Esperanza Tengo todo ese derecho. Buena suerte!)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top