Cambiar los valores del diccionario equivocado al utilizar MVA con NSOperationQueue?
-
26-09-2019 - |
Pregunta
Yo estaba trabajando a través de un ejemplo en el capítulo de concurrencia de "Más iPhone 3 Desarrollo", y no puedo conseguir MVA en un trabajo NSOperationQueue
como se esperaba. Creo una NSOperationQueue
y observar su matriz operations
usando:
NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
self.queue = newQueue;
[newQueue release];
[queue addObserver:self
forKeyPath:@"operations"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:NULL];
Cuando se añade el primer NSOperation
a la cola, espero que se añadirá a su gama operations
subyacente (que la documentación IOS dice es MVA-compatible) y, por tanto, en el diccionario cambio, para encontrar una correspondencia de NSKeyValueChangeKindKey
a NSKeyValueChangeInsertion
, junto con una correspondencia de NSKeyValueChangeNewKey
a la NSOperation
añadido. Pero yo no estaba viendo cualquier tipo de valor NSKeyValueChangeInsertion
.
Sé que el depurador es pro y todo, pero en el interés de tener algo útil para copiar aquí, empecé mi método de observador en:
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
NSNumber *kind = [change objectForKey:NSKeyValueChangeKindKey];
NSObject *newValue = [change objectForKey:NSKeyValueChangeNewKey];
NSObject *oldValue = [change objectForKey:NSKeyValueChangeOldKey];
NSIndexSet *indexes = [change objectForKey:NSKeyValueChangeIndexesKey];
NSLog(@"kind=%d, newValue=%@, oldValue=%@, indexes=%@",
[kind integerValue], newValue, oldValue, indexes);
Y que las impresiones:
2010-11-18 20:01:56.249 Stalled[2692:6f07] kind=1, newValue=(
"<SquareRootOperation: 0x5f51b40>"
), oldValue=(
), indexes=(null)
2010-11-18 20:01:56.250 Stalled[2692:6f07] kind=1, newValue=(
"<SquareRootOperation: 0x5f51b40>"
), oldValue=(
"<SquareRootOperation: 0x5f51b40>"
), indexes=(null)
(SquareRootOperation
es simplemente mi subclase de NSOperation
que anula main
adecuadamente y Stalled
es simplemente el nombre del proyecto.) Pero tenga en cuenta que el método se llama dos veces al insertar una sola operación, y en ambas ocasiones con un valor de tipo de 1, lo que es NSKeyValueChangeSetting
, no NSKeyValueChangeInsertion
. Además, newValue
y oldValue
parecen ser la matriz en sí, no el elemento añadido.
Algunas ideas? Gracias!
Solución
Los documentos dicen -operations
es MVA-compatible, pero no se especifica a qué detalle serán las notificaciones. En la práctica, parece que sólo se le dijo que se ha producido un cambio, por lo que tendría que comparar los valores antiguos y nuevos para averiguar lo que estaba insertado.
No hay que olvidar que estas notificaciones se pueden enviar a usted en cualquier tema!
Otros consejos
La propiedad de las operaciones NSOperationQueue no tiene un tipo mutable (vuelve NSArray*
). Por lo tanto, no implementa los a-muchos métodos de cumplimiento indexados para matrices mutables por lo que nunca ve los eventos de inserción, sólo el evento de cambio para toda la gama.
Editar
Shadowmatter ha planteado el hecho de que en realidad el objeto devuelto es un NSMutableArray
. Esto no significa, sin embargo, cambia nada. En primer lugar, documentación de Apple es clara sobre el tema. Si un método se anuncia a devolver un objeto inmutable, debe respetar la API. No debe utilizar isKindOf:
para averiguar si realmente es mutable y que definitivamente no debe cambiarlo.
La API dice que las operaciones regresen tipo es inmutable y por lo tanto se deben tratar como tal. Más importante aún para esta pregunta, ya que no es una propiedad de colección mutable, no es valor de la clave de codificación compatible para la matriz de valores KVC mutables. Para el cumplimiento colección indexada mutable, la clase tiene que
- implementar uno o ambos de los métodos
-insertObject:in<Key>AtIndex:
o-insert<Key>:atIndexes:
.- implementar uno o ambos de los métodos
-removeObjectFrom<Key>AtIndex:
o-remove<Key>AtIndexes:
.
(tomada directamente de la guía de Apple KVC)
El diseñador de la clase NSOperationQueue
diseñado la propiedad operations
como inmutable y por lo tanto omitido deliberadamente los métodos anteriores.