cocoa nsmutablearray key-value-coding

cocoa - ¿Cuál es el patrón de búsqueda KVC para mutableArrayValueForKey?



nsmutablearray key-value-coding (1)

El NSMutableArray que regresa de llamar a mutableArrayValueForKey: es en realidad una subclase privada de NSMutableArray que anula los métodos de la matriz normal como -count , -objectAtIndex: -insertObject:atIndex: etc. y llama a los métodos KVC correspondientes en el objeto de la matriz. recuperado de. Básicamente, actúa como un proxy para manipular la relación To-many del objeto, y no es algo que deba preocuparse por crear o devolver. Un ejemplo rápido de uso:

Playlist* aPlaylist; Track* aTrack; NSMutableArray* mutableTracks = [aPlaylist mutableArrayValueForKey:@"tracks"]; [mutableTracks insertObject:aTrack atIndex:0];

Este fragmento de código agrega una pista al principio de la lista de reproducción. Si la clase Lista de reproducción implementa métodos KVC para su relación de "pistas", al llamar a un método en la matriz mutable se obtendrá la llamada del método apropiado en el objeto subyacente. Entonces, en este ejemplo, cuando llama a insertObject:atIndex: en la matriz, la matriz llamará a su vez insertObjectInTracks:atIndex: en el objeto de lista de reproducción, y la pista se agrega a la matriz de pistas de la lista de reproducción.

Ahora, en este ejemplo, por supuesto, simplemente puede llamar a insertObjectInTracks:atIndex: directamente, pero hay varias ventajas que puede obtener al usar mutableArrayValueForKey: lugar.

  • La envoltura de matriz oculta los detalles de implementación de los métodos KVC subyacentes. No es estrictamente necesario implementar la lista completa de métodos para ser compatible con KVC. La clase Playlist podría implementar -tracks y -setTracks: y el código anterior aún funcionará. En este caso, en lugar de llamar a insertObjectInTracks:atIndex: el proxy de la matriz mutable creará una nueva matriz con el objeto insertado al principio y luego llamará a setTracks: en el objeto de la lista de reproducción. Obviamente, esto es menos eficiente, por lo que generalmente se recomienda implementar la lista completa de métodos KVC.
  • En el caso de que, en lugar de una cadena constante para la clave, tenga una variable, utilizando mutableArrayValueForKey: permite manipular la relación sin tener que saber los nombres exactos de los métodos a los que tiene que llamar. Siempre que el objeto sea compatible con KVC para la clave que está utilizando, todo "simplemente funcionará".
  • También le permite usar cualquier método que implementa NSMutableArray , así que, por ejemplo, podría usar métodos que busquen objetos en la matriz, NSMutableArray la matriz, etc. sin tener que volver a escribir versiones especiales para lidiar con las cosas de KVC.

Estoy intentando entender un poco mejor el mecanismo de Codificación de clave-valor (KVC) de Cocoa. He leído la Guía de programación de valor-clave de Apple, pero todavía estoy un poco confundido acerca de cómo ciertos métodos KVC buscan claves. En particular, mutableArrayValueForKey:.

A continuación, explicaré cómo entiendo que valueForKey: " valueForKey: " de valueForKey: KVC. Entonces llegaré a mi pregunta sobre mutableArrayValueForKey.

Hay siete métodos KVC "getter" diferentes:

- (id)valueForKey:(NSString *)key; - (id)valueForKeyPath:(NSString *)keyPath; - (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys; - (NSMutableArray *)mutableArrayValueForKey:(NSString *)key; - (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath; - (NSMutableSet *)mutableSetValueForKey:(NSString *)key; - (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;

Al buscar un valor dentro de una propiedad (llamada myKey ), los documentos de Apple indican que valueForKey: busca de esta forma:

  1. Intenta -getMyKey , -myKey y -isMyKey (en ese orden) dentro del receptor
  2. Si no se encuentra, intenta estos get-ordenados, para muchos (NSArray):

    // Required: - (NSUInteger)countOfMyKey; // Requires At Least One: - (id)objectInMyKeyAtIndex:(NSUInteger)index; - (NSArray *)myKeyAtIndexes:(NSIndexSet *)indexes; // Optional (improves performance): - (void)getMyKey:(KeyClass **)buffer range:(NSRange)inRange;

  3. A continuación, intenta con estos getters desordenados, para muchos (NSSet):

    - (NSUInteger)countOfMyKey; - (NSEnumerator *)enumeratorOfMyKey; - (KeyClass *)memberOfMyKey:(KeyClass *)anObject;

  4. A continuación, intenta acceder a las Variables de instancia directamente, asumiendo que YES es devuelto por accessInstanceVariablesDirectly , en este orden: _myKey , _isMyKey , myKey , isMyKey .

  5. Por último, se da por vencido y llama a la clase receptora - (id)valueForUndefinedKey:(NSString *)key método de - (id)valueForUndefinedKey:(NSString *)key . Por lo general, un error se plantea aquí.

Mi pregunta es, ¿cuál es el patrón de orden de búsqueda para mutableArrayValueForKey :?

Los documentos de Apple afirman esto :

Patrón de búsqueda de accesores para colecciones ordenadas

El patrón de búsqueda predeterminado para mutableArrayValueForKey: es el siguiente:

Se busca en la clase del receptor un par de métodos cuyos nombres coincidan con los patrones -insertObject: inAtIndex: y -removeObjectFromAtIndex: (correspondiente a los métodos primitivos NSMutableArray insertObject: atIndex: atIndexes: y removeObjectAtIndex: respectivamente), o métodos que coincidan con el patrón de inserción: indice : y -removeAtIndexes: (correspondientes a los métodos NSMutableArrayinsertObjects: atIndexes: y removeObjectsAtIndexes:). Si se encuentra al menos un método de inserción y al menos un método de eliminación, cada mensaje NSMutableArray enviado al objeto de proxy de colección dará como resultado una combinación de -insertObject: inAtIndex :, -removeObjectFromAtIndex :, -insert: atIndexes :, and -removeAtIndexes: messages siendo enviado al receptor original de mutableArrayValueForKey :. ... etc ...

Esto no tiene sentido para mí, ya que está discutiendo los métodos tipo "setter". mutableArrayValueForKey: devuelve un NSMutableArray. Todos los métodos enumerados anteriormente devuelven el vacío, y se utilizan para editar un NSMutableArray, no para obtenerlo. Ejemplo:

- (void)insertMyKey:(KeyClass *)keyObject inMyKeyAtIndex:(NSUInteger)index; - (void)removeObjectFromMyKeyAtIndex:(NSUInteger)index;

¿Alguna idea de lo que Apple está tratando de decir en sus documentos, o si esto es quizás un error?

Mi teoría es que mutableArrayValueForKey: probablemente esté tomando una ruta similar a valueForKey: al buscar para recuperar un valor KVC. Simplemente no estoy seguro de qué camino es realmente.

¡Gracias por cualquier ayuda que pueda ofrecer! :)