Блоки кода полностью заменяют делегатов? - PullRequest
25 голосов
/ 03 января 2011

Теперь, когда наконец-то поддерживаются блоки для разработки iphone / ipad, они полностью устраняют необходимость в делегатах или делегаты все еще чище в качестве полной реализации интерфейса, в то время как блоки больше подходят для отдельных задач?

Ответы [ 6 ]

42 голосов
/ 27 января 2012

Я искал официальную документацию по этому вопросу, но пока не нашел ни одной.Основываясь на рассмотрении новых классов, представленных в iOS 5, и тех дополнений, которые были внесены в уже существующие классы, я рекомендую своей команде предположить протокол делегата, но вместо этого предоставить блок, когда существует прямая причинная связь * 1002.* между этим конкретным вызовом и производительностью блока.

Таким образом, как правило, протокол делегата является правильным, когда есть необходимость в постоянном общении, действия, вызывающие общение, являются диффузными или исходят из действий.из третьего источника.Блоки в основном связаны с асинхронными действиями и, в частности, с единичными выстрелами.

РЕДАКТИРОВАТЬ: так, некоторые примеры:

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

NSURLConnection +sendAsynchronousRequest:queue:completionHandler: правильно принимает блок для выдачи результатов, потому что (i) есть только один результат для отчета;и (ii) отчет возвращается как прямое следствие действий, предпринятых звонящим.

9 голосов
/ 03 января 2011

Интересная мысль - хотя вы могли бы использовать блок / замыкание вместо метода обратного вызова, я не понимаю, как это можно было бы использовать для замены системы делегатов - после всего делегирования это почти средство объекта объектукоммуникация и, следовательно, возможности намного богаче, чем просто выполнение произвольного фрагмента кода.

Таким образом, я должен согласиться с вашим комментарием «более подходящим для отдельных задач» (и даже тогда толькоопределенные отдельные задачи).

8 голосов
/ 14 марта 2012

Я пытался решить, должен ли я оставить комментарий к другим ответам или оставить собственный ответ.Я решил, и вот оно.

Я в первую очередь разработчик на C #, поэтому я легко вижу, как можно заменить весь шаблон делегирования на блоки, потому что C # всегда рассматривал глаголы как граждан первого класса.На самом деле, это было одним из самых сложных моментов, когда я начал работать с Java и платформой Android.Этот опыт облегчил мне процесс изучения Objective-C и Cocoa.

Я думаю, что это детали реализации модели наблюдателя и модели делегирования, к которым я не особенно чувствую.У меня довольно сложная композиция, а не ориентированная на наследование, поэтому я часто использую шаблон делегирования, даже в C #.

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

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

Недавно я интегрировал GameKit в одну из своих игр и обнаружил, что большинствоасинхронные вызовы (на самом деле, все те, что я использовал) не используют делегатов;они используют блоки.Я думаю, что если бы они могли переписать UIAlertView сегодня, они, вероятно, использовали бы блоки вместо делегатов для обработки обратных вызовов после ввода данных пользователем.Конечно, это всего лишь предположение.

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

1 голос
/ 23 мая 2013

Я делаю свое собственное исследование по этому вопросу, и я нашел эту статью очень поучительной, написанной Джастином Дрисколлом, и я надеюсь, что она может помочь и кому-то еще.

Вот ссылка: Связь с блоками в Objective-C

0 голосов
/ 15 марта 2019

Краткий ответ: Да . Но вы, вероятно, не хотите это сделать, потому что это будет очень избыточно.

Давайте рассмотрим наиболее распространенный вариант использования делегата - CollectionViewDelegate и предположим, что мы хотим использовать его самый популярный метод - collectionView: didSelectItemAtIndexPath.

С делегатом нам нужно сделать только одно:

    @interface MyView () <UICollectionViewDelegate>
    @end

    @implementation MyView {
    ...
    -(void)collectionView:(UICollectionView *)collectionView 
           didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

        // add the implementation here.
    }

Как нам этого добиться только с помощью блока?

    @implementation MyView {
     ...   
     void (^didSelectItemAt)(NSIndexPath*) = ^(NSIndexPath *indexPath) {
          // do a bunch of things to display the cell
          URLFromCell();
          PaneFromURL();
          self.NavigationController.pushView();
      }         
    }

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

В конце давайте посмотрим на определения Apple делегата и блока:

«Делегат - это объект, который действует от имени или в координации с другим объектом, когда этот объект встречает событие в программе.»

Пока блок «Класс Objective C определяет объект, который объединяет данные со связанным поведением».

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

0 голосов
/ 09 июня 2017

Делегаты - Вы можете использовать делегат, когда хотите узнать Процесс / События / Состояние. Например, в NSURLConnectionDelegate вы получите статус данных с помощью двух или более методов делегата .didReceive: NSData connectionDidFinishLoading

Блоки - Вы можете использовать блокировку только тогда, когда ожидаете результата или ошибки

Лучшая ссылка - http://blog.stablekernel.com/blocks-or-delegates/

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