Какой самый хороший способ сделать наблюдателя / наблюдаемого в объективе-C (версия для iPhone) - PullRequest
14 голосов
/ 03 октября 2008

Я привык кодировать пользовательские интерфейсы Java Swing, и в тех случаях, когда у вас есть некоторые свойства, которые меняются, и вы хотите, чтобы ваш пользовательский интерфейс обновлялся, вы должны реализовать шаблон наблюдателя / наблюдаемого. В Java вы обычно делаете это, когда ваш класс ведет список слушателей, которых он уведомляет о различных событиях.

Я играл с Objective-C на Mac, у которого есть KVC и привязка, которая, кажется, работает очень хорошо и требует меньше кода. IPhone SDK, похоже, не обладает такой функциональностью, поэтому мой вопрос: Если у меня есть класс, содержащий данные, которые изменяются, какой лучший способ для меня зарегистрировать компонент пользовательского интерфейса в этом классе, чтобы он мог получать уведомления об изменениях данных, которые он должен отображать?

Ответы [ 3 ]

37 голосов
/ 03 октября 2008

Существует два встроенных способа наблюдения в Какао: наблюдение значения ключа и уведомления. Ни в одной из систем вам не нужно поддерживать или уведомлять собрание наблюдателей самостоятельно; Фреймворк с этим справится.

Наблюдение значения ключа (KVO) позволяет вам наблюдать свойство объекта - включая даже свойство, представляющее коллекцию - и получать уведомления об изменениях этого свойства. Вам просто нужно отправить объект -addObserver:forKeyPath:options:context:, передающий объект, для которого вы хотите получать обновления, ключевой путь свойства (относительно получателя), для которого вы хотите получать обновления, и типы обновлений, которые вы хотите получать. (Существуют аналогичные методы, которые вы можете использовать, если хотите наблюдать свойство, представляющее коллекцию.)

Уведомления старше и тяжелее. Вы регистрируетесь с NSNotificationCenter - обычно центром по умолчанию - парой объектов и селекторов, чтобы получать уведомление при возникновении события. Сам объект уведомления может содержать произвольные данные через его свойство userInfo, и вы можете выбрать просмотр всех уведомлений с определенным именем, а не тех, которые относятся к определенному объекту.

Что вы должны использовать в каждом конкретном случае? В общем, если вы заботитесь об изменениях в определенном свойстве определенного объекта, используйте Key-Value Observing. Вот для чего он предназначен, и он намеренно легкий. (Среди прочего, это основа, на которой строятся привязки Какао.) Если вас волнует изменение состояния, которое не представлено свойством, тогда уведомления более уместны.

Например, чтобы оставаться в синхронизации, когда пользователь меняет имя объекта модели, я бы использовал KVO. Чтобы узнать, когда был сохранен весь граф объектов, я бы использовал уведомления.

9 голосов
/ 03 октября 2008

Я также обнаружил, что вы можете сделать:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleWhateverChange) name:@"whateverChange" object:nil];

Чтобы зарегистрироваться для изменения событий, и

[[NSNotificationCenter defaultCenter] postNotificationName:@"whateverChange" object:nil];

Уволить их. Я мог бы быть N00b, но я просто не мог заставить наблюдателя найти ключ, который мог бы работать для меня.

0 голосов
/ 03 октября 2008

Обычно это не так. Взгляните на обсуждение здесь , в частности ссылку на документацию Apple.

Если вы все еще хотите сделать это так, как вы говорите, не так сложно реализовать что-то вроде привязок «вручную». Вы просто создали бы «привязывающий» объект, который знает, как подписаться на изменения и подключается к свойству представления.

Чтобы на самом деле ответить, как это делается - обычно у вас есть объект контроллера, который отслеживает состояние модели (действует как наблюдатель) и обновляет объект (ы) представления при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...