¿Cuál es la diferencia entre valueforKey :, objectForKey :, y valueForKeyPath :?

Tengo 2 preguntas:

  1. ¿Cuál es la diferencia entre valueForKey: y objectForKey: 😕 ¿Es ese uno para NSDictionary s ( objectForKey: y para otros es valueforKey: o es al revés?

  2. Además, ¿cuál es la diferencia entre valueForKey: y valueForKeyPath: 😕 ¿Tiene algo que ver con Core Data?

Por favor ayuda.

valueForKey: forma parte del protocolo NSKeyValueCoding y, por lo tanto, forma parte del marco de encoding de clave-valor, que le permite acceder a las propiedades de clase por nombre en tiempo de ejecución. Así es como se cargan las NIB, por ejemplo, se cargan los nombres de las propiedades asociadas a las conexiones y luego los valores se establecen directamente por su nombre. Esto contrasta con la forma en que las herramientas de diseño de interfaces visuales a menudo funcionan en otros idiomas, generando una gran cantidad de códigos ocultos comstackdos estáticamente.

objectForKey: se define solo en los diccionarios y busca un objeto por su clave. Un NSDictionary es una clase que almacena conexiones entre valores y claves.

Entonces, valueForKey: podría usarse en un NSDictionary para devolver metainformación sobre el diccionario, como el recuento de objetos dentro de ella, la lista de todas las claves, etc. objectForKey: se usaría realmente para mirar en el diccionario.

En tiempo de ejecución, la diferencia es que objectForKey: es un método con una implementación completamente opaca. valueForKey: se basa explícitamente en llamar posteriormente a getters y setters con nombre. La razón de esto último es que puede extender la encoding de valores-clave a la observación de valores-clave, donde solicita que se le informe cada vez que una propiedad en particular en un objeto en particular cambie. En el tiempo de ejecución, esto se logra con un método swizzle, donde el setter original es reemplazado por uno nuevo que llama al setter anterior y luego envía los mensajes requeridos. Debido a que todos los mensajes se envían dinámicamente, eso solo se logra modificando las tablas dentro de la instancia del objeto.

Por lo tanto, cualquier objeto que sea compatible con la encoding de clave-valor (lo que significa declarar e implementar sus propiedades de la manera adecuada, que la syntax new-ish @ property / @ sintetiza automáticamente) se puede observar sin que el objeto tenga que implementar ningún código .

Hay más cosas de Apple que usan códigos de clave-valor para lograr varias cosas, incluyendo CoreData, pero no es específicamente para habilitar cualquier otra tecnología.

valueForKeyPath: es como valueForKey: excepto que puede atravesar varios objetos. Entonces puede tener un objeto raíz con un conjunto de propiedades, cada una de esas propiedades es otro objeto con otro grupo de propiedades, etc., y usando una ruta clave puede recuperar una salida de valor en la hoja de esa estructura de datos en lugar de tener para iterar a través del objeto después del objeto por ti mismo.

En resumen, valueForKey: y valueForKeyPath: proporcionan información sobre instancias de objetos e interactúan con la naturaleza dinámica del tiempo de ejecución de Objective-C. objectForKey: es un método específico de diccionario que realiza tareas de diccionario.

Adiciones:

Un ejemplo, codificado mientras escribo y suponiendo que NSDictionary es compatible con la encoding de clave-valor:

 NSDictionary *someDictionary; // create someDictionary, populate it, for example (note: we assume photoOfKeys.jpg // definitely exists, not a good idea for production code — if it doesn't we'll get // a nil there and anything after it won't be added to the dictionary as it'll appear // that we terminated the list): someDictionary = @{ @"favouriteGarment": @"hat", @"@allKeys" : [NSImage imageNamed:NSImageNameDotMac], @(2) : NSArray.new }; NSObject *allKeys; // we make no assumptions about which type @allKeys will be, but are going to assume // we can NSLog it, so it needs to be a descendant of NSObject rather than 'id' so as // to definitely respond to the 'description' message — actually this is just compile // time semantics, but if someone else reads this code it'll make it obvious to them // what we were thinking... // some code to get all of the keys stored in the dictionary and print them out; // should print an array containing the strings 'favouriteGarment', '@allKeys' and // the number 2 allKeys = [someDictionary valueForKey:@"@allKeys"]; NSLog(@"%@", allKeys); // some code to get the object named '@allKeys' from the dictionary; will print // a description of the image created by loading photoOfKeys.jpg, above allKeys = [someDictionary objectForKey:@"@allKeys"]; NSLog(@"%@", allKeys); // `objectForKey is analogous to `objectForKeyedSubscript:`, aka allKeys = someDictionary[@"@allKeys"]; 

allKeys es una propiedad de NSDictionary como se describe aquí . También agregué un mapeo de NSString allKeys a una fotografía de algunas teclas. Si utilizo el valor clave de encoding valueForKey: methods o el objectForKey: NSDictionary objectForKey: lookup dicta si leo la propiedad de la instancia del objeto o si envío un mensaje a la instancia del objeto pidiéndole que haga su trabajo único.

  1. objectForKey: es un método en NSDictionary para acceder al objeto asociado con una clave. valueForKey: es un método en NSObject para acceder a cualquier valor asociado con cualquier objeto, a través del nombre de un método de acceso, propiedad y / o variable de instancia.
  2. valueForKeyPath: se puede ver como una forma abreviada de varias llamadas a valueForKey: Puedes pensar que es una especie de xpath, si quieres.

Estas dos declaraciones darán como resultado el mismo resultado:

 // Using nested valueForKey: NSLog(@"%@", [[myObject valueForKey:@"foo"] valueForKey:@"bar"]); // Can be done with a single valueForKeyPath; NSLog(@"%@", [myObject valueForKeyPath:@"foo.bar"]); 

valueForKey: y valueForKeyPath: son parte de KVC (Key Value Coding). La introducción y la documentación detallada se pueden encontrar aquí: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueCoding/

  1. valueForKey: y valueAtKeyPath: son métodos definidos en el protocolo informal NSKeyValueCoding , y las implementaciones predeterminadas para ambas son proporcionadas por la clase raíz NSObject .

    objectForKey: es un método en NSDictionary .

  2. valueForKey: toma una clave para una propiedad, mientras que valueAtKeyPath: toma una llamada keypath. Un keypath es una ruta delimitada por el período a una propiedad específica, como @"relationship.property" .