Objective-C Cocoa Touch: делегаты - я почти понял. Последние шаги - PullRequest
1 голос
/ 26 марта 2012

ОК, я почти все понял.Я много читал в Objective-C, и я действительно хочу понять делегирование, потому что это кажется очень важным для Cocoa-Touch, и я хочу разработать приложение для iPhone.

Итак, делегат - это объектэто может быть дано определенное задание.Говорят, что он следует «протоколу», если он реализует определенные функции.Так, например, контроллер представления может сказать «эй, я не уверен, откуда взять эти данные ... или эй, я не уверен, как отформатировать эту вещь ... вы можете сделать это для меня?"и делегат вроде «уверен, что я тебя покрою».

ОК, это имеет смысл для меня.Что не имеет смысла для меня, так это то, как я заставляю делегата возвращать данные в контроллер представления.Например, мой делегат может перейти по URL-адресу и прочитать результаты спортивных состязаний или что-то в этом роде.Поэтому я говорю «делегат, дайте мне этот счет» ... как заставить контроллер представления сказать «получил, вот оно», а затем поместить его в контроллер представления.Здесь может быть пробел в моем понимании.Должен ли я создать экземпляр контроллера представления внутри делегата?Это не имеет смысла для меня ... потому что тогда у меня будет два контроллера представления ... Не стесняйтесь менять мою аналогию, если вы можете сделать это более ясным.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 26 марта 2012

Я думаю, что вы запутались, потому что похожий шаблон используется (но не ограничивается!) Для двух общих задач, обе из которых применимы к вашей ситуации.

Узоры

  • Наличие внешнего объекта предоставляет данные для вас (это обычно называется источником данных ). См., Например, протокол UITableViewDataSource .

    Это реализуется с помощью возвращаемого значения из метода: например,

    - <b>(UITableViewCell *)</b>tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    Объект , реализующий протокол , возвращает вызывающей стороне некоторое значение (в данном случае, ячейку).

    Я упомяну об источниках данных: сам источник данных (объект, реализующий протокол) обычно содержит больше пользовательской логики вашего приложения, в то время как контроллер , которому требуется источник данных может быть более общим. Например, UITableView - это универсальный контроллер представления, который отображает табличное представление, в то время как класс, реализующий протокол UITableViewDataSource, должен знать детали базы данных вашего приложения.

    (Однако, если быть точным, вы часто создаете подкласс UITableView для пользовательской логики, но чаще всего это логика представления, а не бизнес-логика.)

    Эти методы вызывают логику вашего приложения и, как ожидается, немедленно возвратят .

  • Предоставление обратных вызовов после завершения загрузки данных.

    Например, класс NSURLConnection имеет соответствующий протокол NSURLConnectionDelegate . Наиболее распространенный шаблон использования:

    1. Ваш объект создает NSURLConnection с самим делегатом .
    2. Вы настраиваете и запускаете соединение.
    3. Вы получаете прогресс и данные с помощью методов делегата, которые вы реализуете.

    В этом случае объект , для которого требуется делегат , является вспомогательным объектом, который знает, как загрузить данные из URL-адреса в фоновом режиме. Методы делегата представляют собой обратные вызовы для логики вашего приложения и вызываются в любое время после того, как объекту приказано начать загрузку данных (или того, для чего он предназначен).

  • Делегирование также используется для других вещей в iOS, таких как задачи, связанные с пользовательским интерфейсом, выполняемые объектами, соответствующими UITableViewDelegate .

Ваша ситуация

Все это зависит от того, что представляет из себя ваше приложение и за что отвечает ваш контроллер представления - но, похоже, вы хотите, чтобы контроллер представления делегировал загрузку данных - в основном ему нужен источник данных, (Вам также следует подумать, может ли встроенный UITableView & UITableViewDataSource удовлетворить ваши потребности.) Но если ваш источник данных собирается асинхронно загружать данные из Интернета, ему может потребоваться реализовать некоторые обратные вызовы для загрузки данных через что-то вроде NSURLConnection.

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

Вот почему в UITableView есть метод -reloadData, поэтому объект, который служит источником данных, может сообщить ему, когда данные доступны . Возможно, вы захотите использовать такой шаблон в своем приложении.

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

1 голос
/ 26 марта 2012

Определите методы вашего протокола с возвращаемыми значениями.

Тем не менее, получение URL-адреса является плохим примером, так как ожидание делегата для возврата результатов блокирует вызывающий поток.В этом случае у делегата должен быть способ перезвонить с результатами, когда это будет сделано.Это может быть достигнуто либо передачей делегата делегату, либо передачей делегату одного или нескольких блоков Objective-C (onSuccess, onError,…).

В этом случае блоки гораздо проще кодировать, чемделегаты и протоколы и постепенно вытесняют их в API Apple и сторонних разработчиков.

...