Безопасное ключевое значение Наблюдение за ключами

Я пытаюсь реализовать наблюдение за безопасным ключевым ключом по ключевым путям. Предположим, что у меня есть объект модели данных с именем person, у которого есть свойство workplace. workplace в свою очередь имеет свойство address, которое я хочу наблюдать, поэтому я настраиваю наблюдение за ключевым значением со следующим вызовом:

[person addObserver:theObserver 
         forKeyPath:@"workplace.address" 
            options:NSKeyValueObservingOptionNew 
            context:NULL];

Это отлично работает, пока человек не изменит рабочее место. Как только это произойдет:

person.workplace = newWorkplace;

система KVC автоматически сбрасывает приложение, заявив, что "oldAddress был освобожден, пока наблюдатели с ключевыми значениями все еще были зарегистрированы с ним". (oldAddress - адрес предыдущего рабочего места).

К сожалению, я не могу настроить реализацию класса объекта "person", чтобы уведомить наблюдателя о том, что рабочее место уйдет. Есть ли какой-либо шаблон, чтобы избежать такого рода сбоев? Может быть, можно получить другие уведомления? Как проходит ключевой путь в случае KVC и у вас есть доступ к этой цепочке?

Ответ 1

Изменить 2

Проведя еще некоторое время с KVO, я обнаружил, что в вашем случае вы должны наблюдать person.workplace.address вместо workplace.address. Когда вы наблюдаете person.workplace.address, вы достигаете двух вещей:

1) Поскольку у вас есть объект person, у вас есть абсолютный контроль над жизненным циклом вашего объекта. Теперь вы можете удалитьObserver по своему усмотрению.

2) Когда объект workplace изменен, механизм KVO будет "автоматически" наблюдать новый address нового workplace. Конечно, он уведомит вас о новом address.

Теперь вы можете наблюдать address, не опасаясь, что workplace заменяется в произвольное время. Это одна из истинных скрытых возможностей KVO. Это позволяет подклассам безопасно наблюдать любые объекты суперкласса, не зная об их жизненных циклах.

Изменить 1

Лучшая практика удаления объекта в качестве наблюдателя для некоторого свойства KVO

Принятый ответ в этой теме лучше всего описывает вашу ситуацию. Вам не следует в первую очередь наблюдать свойство address, так как вы не контролируете жизненный цикл workplace. У вас проблемы с дизайном.

Оригинал

Вы можете наблюдать keyPath workplace на объекте person. Когда этот keyPath вызывается, вы просто удаляетеObserver для workplace.address.

[человек addObserver: theObserver          forKeyPath: @ "рабочее место"             Варианты: [NSKeyValueObservingOptionNew]             Контекст: NULL];