2012-01-18 2 views
4

Я новичок в программировании на Mac, и я работаю над документированным приложением.Избегайте соединения в приложении на основе какао на основе документов?

Подкласс NSDocument создает подкласс NSWindowController. Этот оконный контроллер создает два подкласса NSViewController.

Иногда изменение одного из видов NSViewController должно содержать уведомление NSDocument и/или основной класс модели. Кроме того, изменение модели должно быть уведомлено обо всех/некоторых представлениях.

Мой вопрос: что такое лучший подход, чтобы не было (или минимального) соединения? Я знаю, что есть несколько вариантов, но я не уверен, какой из них лучше всего подходит для моего приложения, как я новичок не в программировании, но и какао и особенно NSDocument:

  • КВО. Выглядит хорошо и легко реализовать, но мне не нравится идея не указывать явным образом наблюдателя (ов) об изменении (AFAIK, self.someProperty = newValue делает автоматическое уведомление наблюдателей), и не нравится тот факт, что вам нужно зарегистрироваться к именам свойств, которые могут измениться во времени.

  • Уведомления. Я знаю, что это такое, и я использовал их для iOS. Но я где-то читал, что они не могут быть немедленно отправлены наблюдателям. Это правда? Если нет, видите ли вы их как хороший подход для приложения на основе документов?

  • Делегаты. Да, в обычных условиях (или, что я обычно видел) класс имеет один делегат. Но создание массива делегатов также работает (просто протестировано). Проблема, которую я вижу здесь, заключается в том, что каждый раз, когда мне нужно уведомлять делегатов, я должен их перебирать, чтобы они отвечали на метод и вызывали этот метод.

Есть ли другие альтернативы, которые мне не хватает?

+0

Уведомления * * немедленно отправляются наблюдателям. –

ответ

1

KVO по классу контроллера является наиболее распространенным способом взаимодействия между моделью и ее видами. Фактически, привязки Cocoa Bindings, предназначенные главным образом для устранения кода на уровне контроллера, основаны на KVO. Это правда, что KVO/KVC полагается на имена свойств, и если эти изменения изменятся, вам придется изменить привязки или настройку KVO, соединяющую ваше представление. Тем не менее, обычно не представляется возможным сделать ваши представления совершенно не осведомленными о конкретной модели, поэтому я не вижу в этом проблемы.

Моя рекомендация будет заключаться в использовании связывания какао, где вы можете, поскольку они устраняют много кода клея. В тех местах, где они не могут использоваться, ваши контроллеры (средний слой в MVC) должны использовать KVO для наблюдения за изменениями модели и обновления соответствующих представлений. Изменения в представлениях могут быть возвращены в модель через устройства доступа к свойствам и/или KVC с помощью контроллеров.

+1

Я не согласен с тем, что вы не можете полностью понять ситуацию с моделью. Если это так, «NSTableView» не может работать практически для каждого разработчика Cocoa. Используйте доступные шаблоны (привязки, делегаты, источники данных), и вы можете определенно сделать представление полностью независимым, и на самом деле это должно быть вашей целью. –

+0

Да, ты прав. Представления могут не знать о модели, но уровень контроллера должен знать о деталях как модели, так и представлений. OP действительно спрашивает о уровне контроллера (NSViewControllers и NSWindowControllers). NSTableView сам по себе не знает модель, но контроллер (ы), используемый для подключения к модели, безусловно, должен знать специфику модели, поэтому неплохо иметь жестко закодированные пути ключей в классах контроллера. –

+0

@AndrewMadsen Спасибо. Просто переключился на KVO и заметил более чистый код, за исключением одного случая, когда я явно должен вызывать _willChangeValueForKey_ и _didChangeValueForKey_, потому что наблюдатели не замечали об изменениях, если я не называю эти методы. Опять же, я довольно новичок в KVO, и я знаю, что классы должны быть совместимы с KVC, но это одно и не уведомляет наблюдателей. По-прежнему нужны некоторые знания, я думаю ... – msoler

1

Да, в нормальных условиях (или, что я обычно видел), класс имеет один делегат. Но создание массива делегатов также работает (только проверил его).

Делегаты часто используются для изменения поведения делегирующего объекта. Хорошим примером является делегирование приложений: NSApplication сам по себе не очень интересен; он полагается на своего делегата, чтобы определить интересное поведение приложения.Наличие нескольких делегатов, пытающихся изменить поведение одного объекта, может быть проблемой, если различные делегаты конфликтуют друг с другом. Что вы будете делать, если делегаты не согласятся?

В Cocoa есть случаи, когда класс использует более одного делегата, но каждый из них имеет отдельную роль. Например, NSTableView имеет как делегат, так и источник данных, но оба они действительно являются делегатами.

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

Это не сложно решить. Например, вы можете создать NSInvocation для инкапсуляции вызова, а затем отправить вызов каждому «делегату». Однако, если вы это сделаете, вы почти заново изобрели систему уведомлений. Если вам требуется сообщение «один ко многим», которое вы получите с предложением нескольких делегатов, вам, вероятно, будет лучше использовать уведомления или KVO.

+0

Да, мне нужно общение «один ко многим» в большинстве случаев, и делегирование стало немного беспорядочным. Как вы, ребята, предположили, что я переехал в KVO, и он работает очень хорошо. Благодаря! – msoler