Objective-C /Какао: правильный дизайн для делегатов и контролеров

Рассмотрим следующую распространенную ситуацию:

В вашем приложении Какао есть несколько MainView, загруженных из NIB, который контролируется MainViewController. Ваш MainView содержит некоторые элементы управления, такие как UILabel infoLabel. У вас также есть делегат класса MyDelegate, который получает какое-то событие.

Вы хотели бы убедиться, что когда MyDelegate получает свое событие, infoLabel обновляется соответствующим образом. Однако проблема в том, что MyDelegate не имеет ссылки на MainView или MainViewController и не знает о метке.

Одним из решений является передача ссылки MainViewController на объект делегата, но это не так, потому что вы можете оказаться в нежелательной ситуации. где объект имеет ссылки друг на друга.

Каков правильный дизайн для решения этой проблемы?

7 голосов | спросил Jake 4 Maypm09 2009, 20:30:06

4 ответа


0

На неназванном форуме разработчиков кто-то пишет:

  

Короче говоря, я решил, что начну использовать NSNotifications. Стэнфордский онлайн-курс, которым следуют люди, преподают два инженера Apple. Только что они недвусмысленно заявили, что НЕ должны использовать делегат приложения или глобальные переменные, и сказали, что используют NSNotifications, делегаты и наблюдения K-V.

     

Если так говорят инженеры Apple, я собираюсь двигаться в этом направлении.

     

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

     

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

ответил Jake 4 Maypm09 2009, 22:07:03
0

Вот два варианта, которые приходят на ум:

  • Если событие, предназначенное для делегирования, отправляется вашим контроллером, вы можете сделать так, чтобы этот метод возвращал контроллеру значение для отправки в представление.

  • Вы также можете привязать значение infoLabel к некоторому ключу (используя, например, привязки Какао или просто необработанное наблюдение значения ключа). Связанный объект (который может быть делегатом или каким-либо другим объектом модели) может просто обновить связанный ключ, что приведет к передаче значения в infoLabel. Например, вы можете привязать член info к значению infoLabel. Когда делегат получает событие, он может обновить информационный элемент, и представление изменится. Само фактическое связывание может происходить в IB (если ваш делегат находится в кончике) или в контроллере (который имеет ссылку на представление и делегат.)

Последнее решение в основном является циклическим, но мне оно кажется чище.

ответил Jesse Rusak 4 Maypm09 2009, 21:33:18
0

Мы реализовали сложный объект Data, который контролирует почти все. Он проверяет, есть ли изменения, и обновляет все глобальные переменные.

При создании новых экземпляров я ссылаюсь на класс Data следующим образом:

[[Button alloc] initWithData:data]];

Где data - это класс данных Singelton. Теперь мы можем проверить, есть ли изменения, на которые нужно реагировать.

Я признаю, это все еще требует ссылки, как вы описали, хотя. Кажется, здесь нет простой ссылки parent.

ответил Kriem 4 Maypm09 2009, 21:16:08
0

Обычный шаблон, как вы сказали, передает указатель на MainView через его методы делегата. Таким образом, если MainView вызывает doSomethingWithFoo:своего делегата > метод, вы хотите изменить этот метод на:

- (void)mainView:(MainView *)view doSomethingWithFoo:(id)foo

и соответственно вызовите новый метод. Если вы работаете непосредственно с указателем MainView, у вас не должно возникнуть проблем с циклическими ссылками.

ответил Matt Ball 4 Maypm09 2009, 21:12:47

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132