2012-11-12 2 views
3

Je souhaite recevoir une notification lorsque l'objet correspondant à une certaine clé dans une instance NSCache change. J'ai essayé d'utiliser Key-Value Observer sans avoir de chance (la console n'enregistre rien).Key-Value Observing NSCache

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [self.cache addObserver:self forKeyPath:@"myKey" options:NSKeyValueObservingOptionNew context:NULL]; 
    [self.cache setObject:@"myObject" forKey:@"myKey"]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    NSLog(@"KEYPATH CHANGED: %@", keyPath); 
} 

Comment puis-je observer le contenu d'un NSCache?

Répondre

6

Je m'attendrais à ce que NSCache ne soit pas conforme à la valeur-clé (KVO) pour ce type de clé. KVO est implémenté en interne au niveau NSObject en remplaçant le setter normal par un paramètre qui alerte les observateurs pertinents et appelle le setter d'origine. Dans le cas de choses que vous définissez avec setObject:forKey: il n'y a pas de setter spécifique, donc rien pour l'exécution de se bloquer.

Depuis NSCache n'a publié aucune notification pertinente je pense que votre meilleur espoir est the delegate protocol. Ce n'est pas explicite exactement ce qui compte comme une expulsion, mais si cache:willEvictObject: est appelée lorsque l'objet associé à une clé est modifié volontairement, vous pouvez directement le déconnecter.

Sinon, je vous recommande de créer une classe wrapper pour NSCache, dire DWCache pour l'amour de l'argument, qui contient un NSCache, est le délégué du cache, et fournit son propre setObject:forKey:. Il publiera un message approprié (i) lors du premier appel à setObject: forKey :; (ii) à chaque appel subséquent qui fournit un objet différent de celui déjà dans le cache; et (iii) chaque fois qu'il reçoit un cache:willEvictObject:. La seule complexité potentielle est que NSCache ne copie pas les clés d'origine et, en conséquence, n'a aucun moyen d'obtenir la clé de l'objet. Vous pouvez stocker ces connexions séparément, par ex. à travers un NSDictionary. Si vous effacez le dictionnaire lorsque le cache expulse l'objet, vous continuerez à fournir un comportement de mise en cache.

+0

Merci beaucoup, bonne réponse. J'utilise un wrapper personnalisé autour de NSCache qui a une propriété NSCache et NSMutableDictionary. Le wrapper implémente les méthodes personnalisées addObserver et removeObserver KVO qui sont transmises au dictionnaire et implémente également le délégué NSCache pour mettre à jour le contenu du dictionnaire. – datwelk

0

Vous avez à mettre en œuvre cette méthode:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; 

KeyPath est la clé qui a changé, l'objet est la nouvelle valeur.

+0

Ouais c'est ce que je voulais dire par "j'ai essayé d'utiliser KVO". Edité ma question pour être plus clair. – datwelk