Pergunta

Eu estava trabalhando com um exemplo no capítulo de simulta NSOperationQueue trabalhando como esperado. Eu crio um NSOperationQueue e observar seu operations Array usando:

NSOperationQueue *newQueue = [[NSOperationQueue alloc] init];
self.queue = newQueue;
[newQueue release];
[queue addObserver:self
        forKeyPath:@"operations"
           options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
           context:NULL];

Quando o primeiro NSOperation é adicionado à fila, espero que seja adicionado ao seu subjacente operations Array (que a documentação do iOS diz ser compatível com KVO) e, portanto, no dicionário de mudança, para encontrar um mapeamento de NSKeyValueChangeKindKey para NSKeyValueChangeInsertion, junto com um mapeamento de NSKeyValueChangeNewKey para o adicionado NSOperation. Mas eu não estava vendo nenhum tipo de valor NSKeyValueChangeInsertion.

Eu sei que o depurador é profissional e tudo, mas, no interesse de ter algo útil para copiar aqui, iniciei meu método de observador com:

- (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);

E isso impressa:

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 é simplesmente minha subclasse de NSOperation isso substitui main apropriadamente, e Stalled é simplesmente o nome do projeto.) Mas observe que o método é chamado duas vezes ao inserir uma única operação, e as duas vezes com um valor gentil de 1, que é NSKeyValueChangeSetting, não NSKeyValueChangeInsertion. Adicionalmente, newValue e oldValue parece ser a própria matriz, não o item adicionado.

Alguma ideia? Obrigado!

Foi útil?

Solução

Os documentos dizem -operations é compatível com o KVO, mas não especifique com quais detalhes as notificações serão. Na prática, parece que você só é informado de que ocorreu uma mudança, então teria que comparar os valores antigos e novos para descobrir o que foi inserido.

Não se esqueça que essas notificações podem ser enviadas a você em qualquer tópico!

Outras dicas

A propriedade operações do NSoperCeue não possui um tipo mutável (ele retorna NSArray*). Portanto, ele não implementa os métodos indexados de conformidade para matrizes mutáveis, para que você nunca verá os eventos de inserção, apenas o evento de mudança para toda a matriz.

Editar

ShadowMatter levantou o fato de que o objeto realmente devolvido é um NSMutableArray. Isso, no entanto, não muda nada. Primeiramente, Documentação da Apple é claro sobre o assunto. Se um método for anunciado para retornar um objeto imutável, você deve respeitar a API. Você não deve usar isKindOf: Para descobrir se é realmente mutável e você definitivamente não deve alterá -lo.

A API diz que o tipo de retorno das operações é imutável e, portanto, você deve tratá -lo como tal. Mais importante para esta questão, pois não é uma propriedade de coleção mutável, não é compatível com codificação de valor -chave Para os valores de KVC de matriz mutável. Para conformidade com a coleta indexada mutável, a classe precisa

  • Implementar um ou ambos os métodos -insertObject:in<Key>AtIndex: ou -insert<Key>:atIndexes:.
  • Implementar um ou ambos os métodos -removeObjectFrom<Key>AtIndex: ou -remove<Key>AtIndexes:.

(retirado diretamente do guia da Apple KVC)

O designer do NSOperationQueue Classe projetou o operations propriedade como imutável e, portanto, deliberadamente omitiu os métodos acima.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top