Наблюдение ключ-значение NSCache

Я хочу получать уведомления при изменении объекта, соответствующего определенному ключу в экземпляре NSCache. Я попытался использовать Key-Value Observing без удачи (консоль ничего не регистрирует).

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

Как я могу наблюдать за содержимым NSCache?

2 ответа

Решение

Я бы ожидал NSCache не быть совместимым со значением ключа (KVO) для такого ключа. КВО реализуется на внутреннем NSObject уровень путем замены обычного установщика на тот, который предупреждает соответствующих наблюдателей и вызывает первоначальный установщик. В случае вещей, которые вы установили с setObject:forKey: нет конкретного установщика, так что время выполнения не должно зависать.

поскольку NSCache не публикует никаких релевантных уведомлений. Думаю, ваша лучшая надежда - протокол делегатов. Это не совсем точно, что считается выселением, но если cache:willEvictObject: Вызывается, когда объект, связанный с ключом, изменяется намеренно, тогда вы можете напрямую подключиться к нему.

В противном случае я бы порекомендовал вам создать класс-оболочку для NSCache, сказать DWCache ради аргумента, который содержит NSCacheявляется делегатом кеша и предоставляет свой собственный setObject:forKey:, Он отправит соответствующее сообщение (i) при первом вызове setObject:forKey:; (ii) при каждом последующем вызове, который предоставляет объект, отличный от объекта, уже находящегося в кэше; и (iii) всякий раз, когда он получает cache:willEvictObject:,

Единственная потенциальная сложность заключается в том, что NSCache не копирует оригинальные ключи и, отчасти, в результате не имеет средств для получения ключа от объекта. Вы можете хранить эти соединения отдельно, например, через NSDictionary, При условии, что вы очищаете словарь, когда кеш высвобождает объект, вы все равно будете обеспечивать его поведение.

Вы должны реализовать этот метод:

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

keyPath - это ключ, который изменился, объект - это новое значение.

Другие вопросы по тегам