2009-07-09 14 views
19

È possibile osservare (sottoscrivere) le modifiche ai valori memorizzati con chiavi diverse in un NSMutableDictionary? Nel mio caso le chiavi esisterebbero già quando la sottoscrizione è iniziata, ma i valori cambiano e vorrei ricevere una notifica in questo caso. Vorrei la chiave del valore modificato nella notifica.Osservazioni su NSMutableDictionary modifiche

Suppongo che se le mie chiavi del dizionario fossero tutte istanze NSString, potrei semplicemente iscriverti individualmente a ciascun percorso chiave. Ma cosa succede se le mie chiavi sono non-stringhe? Sono sfortunato in quel caso?

risposta

6

Questa è un'idea interessante. Non riesco a trovare nulla in NSDictionary o NSDictionaryController che sembra promettente. Il mio primo istinto sarebbe quello di usare la composizione attorno a un NSMutableDictionary e intercettare le chiamate a setObject: forKey: (e forse -removeObjectForKey :) per notificare ai sottoscrittori le modifiche.

C'è un Cocoa With Love post nella sottoclasse NSMutableDictionary che sarà probabilmente utile se si sceglie di percorrere quella rotta. Ho anche created my own NSMutableDictionary subclasses e sei libero di usare il codice open source.

È possibile progettare un protocollo observer che possa specificare chiavi particolari che devono essere monitorate. Non dovrebbe essere troppo codice, ma più di quanto ho il tempo di buttare giù al momento.

+0

Grazie. Penso che la composizione attorno a un NSMutableDictionary sia la strada da percorrere. Non riesco ancora a vedere come farlo funzionare a meno che le chiavi non siano NSStrings, ma penso che probabilmente potrò lavorare con quello. –

+0

@Quinn Taylor: il collegamento alla sottoclasse personalizzata sembra morto e dovrei controllare questo codice. Ce l'hai ancora in giro da qualche parte? – Cyrille

6

L'ho implementato con successo ora, usando la composizione attorno a NSMutableDictionary. Sono sorpreso di quanto poco codice ci sia voluto. La classe che ho implementato è Board, usata per rappresentare il modello in un gioco da tavolo. Chiunque può iscriversi a cambiamenti per gli stati da tavolo chiamando l'addObserver: metodo, implementato in questo modo:

- (void)addObserver:(id)observer { 
    for (id key in grid) 
     [self addObserver:observer 
       forKeyPath:[key description] 
        options:0 
        context:key]; 
} 

Dal momento che è possibile iscriversi solo ai tasti utilizzando il modello KVO, ho barato, condividendo il descrizione della chiave , ma passando la chiave stessa come contesto. Negli oggetti che osservano le istanze della mia scheda, implemento lo -observeValueForKeyPath:ofObject:change:context: per ignorare la stringa keyPath e utilizzare solo il contesto passato.

La mia semplice classe Board non è conforme a KVO per le proprietà artificiali create con questo metodo, quindi ho passato 0 nella proprietà options in modo che i macchinari KVO non tentano di ottenere i vecchi/nuovi valori di tali chiavi. Ciò farebbe esplodere il mio codice.

Tutto ciò che cambia la scheda (nel mio semplice classe c'è un solo metodo che fa questo) sollevare le necessarie comunicazioni per causare il macchinario KVO per entrare in azione:

- (void)setPiece:(id)piece atLocation:(Location*)loc { 
    [self willChangeValueForKey:[loc description]]; 
    [grid setObject:piece forKey:loc]; 
    [self didChangeValueForKey:[loc description]]; 
} 

Voila! Sottoscrizione a NSMutableDictionary con chiavi non stringa!

+0

L'iscrizione alla descrizione è un bel trucco! –

Problemi correlati