Я успешно реализовал это сейчас, используя композицию вокруг NSMutableDictionary. Я удивлен, как мало кода потребовалось. Класс, который я реализовал, это Board, используемый для представления модели в настольной игре. Любой может подписаться на изменения в состояниях платы, вызвав метод addObserver:, реализованный так:
- (void)addObserver:(id)observer {
for (id key in grid)
[self addObserver:observer
forKeyPath:[key description]
options:0
context:key];
}
Поскольку вы можете подписываться только на ключи, используя модель KVO, я обманул и подписался на описание ключа, но передав сам ключ в качестве контекста. В объектах, которые наблюдают за экземплярами моей доски, я реализую -observeValueForKeyPath:ofObject:change:context:
, чтобы игнорировать строку keyPath и просто использовать переданный контекст.
Мой простой класс Board не совместим с KVO для искусственных свойств, которые я создаю с помощью этого метода, поэтому я передал 0
в свойстве options
, чтобы механизм KVO не пытался получить старые / новые значения этих ключей , Это может привести к взрыву моего кода.
Все, что меняет доску (в моем простом классе есть только один метод, который делает это), вызывает необходимые уведомления, чтобы заставить механизм КВО вступить в действие:
- (void)setPiece:(id)piece atLocation:(Location*)loc {
[self willChangeValueForKey:[loc description]];
[grid setObject:piece forKey:loc];
[self didChangeValueForKey:[loc description]];
}
Вуаля! Подписка на NSMutableDictionary с нестроковыми ключами!