2011-11-19 9 views
8

Así, ya he leído en la documentación que se señala¿Cuál es la diferencia entre KVC y Properties?

Objective-C 2.0 de la sintaxis con punto y sistema de no-valor son ortogonales tecnologías. Puede usar la codificación de clave-valor, use o no la sintaxis de punto, y puede usar la sintaxis de punto ya sea que use KVC o no. Sin embargo, ambos usan una "sintaxis de puntos". En el caso de la codificación de valores-clave, la sintaxis se usa para delimitar elementos en una ruta clave. Es importante recordar que cuando accede a una propiedad utilizando la sintaxis de punto, invoca los métodos de acceso estándar del receptor.

Luego proporcionó un ejemplo que supuestamente mostró la diferencia entre los dos. Sin embargo, todavía no entiendo, ¿cuál es la diferencia entre KVC y los métodos de acceso a la propiedad? ¿No son lo mismo? ¿Y cómo distingo entre puntos que llaman a setValue: forKeyPath: y accesadores simples?

Respuesta

14

Sin embargo, todavía no entiendo, ¿cuál es la diferencia entre los métodos de acceso de propiedades y KVC?

KVC es una forma de llamar a los métodos de acceso a la propiedad o acceder de otra forma a una propiedad.

¿Qué quiero decir con "acceso de lo contrario"? Para propósitos de KVC, una variable de instancia sin métodos de acceso cuenta como una propiedad informal. Obtendrá o establecerá el valor de la variable de instancia directamente si no se puede encontrar ningún par de descriptores de acceso coincidentes. (Sí, esto no vale la pena usarlo en un código moderno. Declare siempre @property para cualquier cosa que intente acceder a otra parte, e inversamente, no use KVC para acceder a nada que no sea propiedad pública)

Propiedad los métodos de acceso son los que KVC llamará si existen (preferidos, tanto por KVC como por cada programador en sí, a través del acceso directo a ivar). Un usuario puede obtener o establecer una variable de instancia, como lo hacen los usuarios sintetizados, o acceder a otro tipo de almacenamiento.

Los accesorios son implementación, las propiedades son interfaz, y KVC es una forma de usarlos.

¿Y cómo distingo entre puntos que llaman a setValue: forKeyPath: y accesos simples?

Una ruta de acceso de clave es una cadena, mientras que una expresión de acceso de propiedad es una expresión. El compilador evalúa una expresión de acceso a la propiedad y la traduce en uno o más mensajes de Objective-C, mientras que KVC evalúa una ruta de la clave en tiempo de ejecución.

Por lo tanto, cuando se utiliza una ruta de la clave:

[someObject setValue:theValue forKeyPath:@"foo.bar.baz"]; 

Usted sabe que es un camino clave porque (1) es una cadena, como se indica en este caso por la sintaxis de cadena literal @"…", y (2) está pasando la cadena de la ruta de la clave al setValue:forKeyPath: para que la evalúe.

El uso de una ruta de tecla utiliza KVC para acceder a las propiedades nombradas. Enviará los mensajes de acceso relevantes en su nombre.

Cuando se utiliza una expresión de propiedad de acceso:

someObject.foo.bar.baz = theValue; 

Usted sabe que es una expresión de acceso a la propiedad, ya que no se está identificando las propiedades con una cadena. Está accediendo a ellos (enviando los mensajes de acceso) usted mismo, en su propio código.

No hay muchas razones para usar KVC de ninguna forma; Cuando conozca la propiedad en autoría/tiempo de compilación, es mejor declarar un @property y acceder a la propiedad usted mismo, ya sea con expresiones de acceso a la propiedad o expresiones de mensaje ([[[someObject foo] bar] setBaz:theValue]). El momento de usar KVC es cuando no sabe a qué propiedad desea acceder hasta el tiempo de ejecución, lo cual es bastante raro. Es principalmente una tecnología de bloque de construcción detrás de KVO, uniones de cacao, partes de Core Animation, etc.

En su mayoría, solo querrá acceder a las propiedades usted mismo.

+4

** "El momento de usar KVC es cuando no sabe a qué propiedad desea acceder hasta el tiempo de ejecución" ** de su respuesta es lo que estaba buscando, gracias. – km3h

+0

Fue muy útil para mí. Tenía en mente que ** El momento de usar KVC es cuando no sabe a qué propiedad desea acceder hasta el tiempo de ejecución, ** esta podría ser la razón, pero no estaba seguro. Me diste confianza sobre mi pensamiento. –

+0

Peter you state ", e inversamente, no use KVC para acceder a nada que no sea propiedad pública."Acabo de descubrir que si una propiedad se declara de solo lectura y luego se redeclara como lectura-escritura en la implementación, entonces KVC escribirá desvergonzadamente sobre esa propiedad. ¿No hay forma de bloquear esto? Intenté (BOOL) accessInstanceVariablesDirectly { return NO;} pero eso no impide que KVC escriba en la propiedad. –

2

La codificación del valor clave le permite establecer y obtener el valor de las propiedades a través del código utilizando el nombre de la cadena de la propiedad. Por ejemplo, si tuviera una llamada foo propiedad que es de tipo NSString:

[self setValue:@"mystring" forKey:@"foo"]; 

// read the value by key 
NSString *s = [self valueForKey:@"foo"]; 

sintaxis con punto es compilar el azúcar sintaxis. Como una preferencia personal (ya que algunos no están de acuerdo - muy bien) Yo no uso la sintaxis con punto pero todavía uso KVC:

[myObj setFoo: @"someString"] 

es igual a:

myObj.foo = @"someString"; 

Ellos son ortogonales, pero diferentes conceptos ambos tratan de cómo interactúa con las propiedades

Finalmente, menciona la sintaxis de la propiedad. Otro concepto ortogonal más relacionado con el tratamiento de las propiedades.

Con objetivo-c, la convención es importante. Siguelos. Las propiedades son el nombre de la propiedad para el obtener y establecer [Nombre] para la asignación:

- (NSString*)foo 
{ 
    return _foo; // defined as (NSString*)_foo in header 
} 

- (void) setFoo: (NSString*)foo 
{ 
    if (foo == _foo) 
     return; 

    NSString* curr = _foo; 

    _foo = [foo retain]; 
    [curr release];  
} 

Ahora, que quiere escribir algo así como que cada vez. Por lo tanto, entrar en la sintaxis @property:

En la cabecera:

@property (retain) NSString *foo; 

Luego, en .m:

@synthesize foo; 

Eso es el equivalente de los descriptores de acceso escritas a mano. Es el azúcar de sintaxis del compilador que amplía el código de propiedad en función de cómo atribuyes las propiedades.

Docs:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

Cuestiones relacionadas