В данный момент я учу себя программированию на iOS, и одной концепцией, которую мне действительно трудно обернуть, является делегирование. Что это такое? Почему и как это используется? В чем преимущество? Техническое письмо из книги, которую я читаю, затрудняет понимание.
11
Ответы:
Чтобы понять
delegates
, ты должен понятьprotocols
.А
protocol
это как контракт на обслуживание. Когда объект (чаще всегоUIViewController
подкласс, но не всегда) подписывает этот контракт, он говорит: «Я заинтересован в предоставлении логики для поддержки отправляемого мной сообщения». Это похоже наNSNotificationCenter
относительно подписавшись на уровне интересов, разница в том , объект , который использует делегирование может иметь только одинdelegate
в то время, когда , как несколько объектов могут подписаться на то же самоеNSNotification
.Apple использует делегирование повсеместно. Тем не менее, все больше и больше вы видите, что Apple переходит на многие из своих API
blocks
, которые похожи наcallbacks
другие языки.При этом делегирование помогает поддерживать MVC, хотя я бы сказал, что делегирование - это сама по себе модель проектирования. Это помогает отделить модели от контроллеров. Как в примере Джона Картрайта, a
UITableView
знает, как отображать строки и разделы. Он знает, как использовать повторноUITableViewCells
по соображениям производительности. Он знает все другие вещи, которыеUIScrollView
знает. Но он не знает, какие клетки отображать. Он не знает, чем заполнить эти клетки. Он не знает, какие клетки повторно использовать для данногоNSIndexPath
. В любом случае, это действительно должна быть работа контроллера. Делегирование позволяет табличному представлению разгрузить эту логику отсутствия представления на объект, который в любом случае должен нести эту ответственность.Более того, вы не привязаны к одному делегату на все время существования объекта. Вы можете очень легко иметь несколько источников данных для данного
UITableView
и переключать их во время выполнения по мере необходимости.Таким образом, с одной стороны, делегирование отлично подходит для предоставления данных и реагирования на взаимодействия с объектом. Вы увидите его в большом количестве классов UIKit, такой
UITableView
,UIPickerView
,UICollectionView
и т.д.Но делегирование также очень полезно, когда вы хотите передавать информацию между объектами. Вы можете очень легко создавать свои собственные протоколы и подписывать свои собственные объекты, чтобы следовать им. Кроме того, методы протокола
@required
по умолчанию, но вы можете указать некоторые методы, которые будут@optional
, Это может дать вам хорошую гибкость, если вам это нужно. Допустим, у вас есть родительский контроллер представления и дочерний контроллер представления. Возможно, вы используете новый Containment API для этого. Как правило, если вам нужно передать информацию от родителя ребенку, вы делаете это с помощью свойства. Готово. Но что, если вам нужно передать информацию от ребенка обратно родителю? Может быть, что-то меняется в ребенке, и вам нужно уведомить родителя. Конечно, вы могли бы сделать некоторые КВО на определенных значениях. Но, может быть, вы хотите знать, когда кнопка нажата. Просто создайте новый протокол в контроллере дочернего представленияВ MyChildViewController, когда ваша кнопка нажата, просто проверьте, отвечает ли ваш делегат на сообщение делегата (если это требуется, и ваш делегат не реализует метод, вы потерпите крах. Вы можете создать метод,
@optional
если вам нужно) и отправить Это:Затем установите делегат вашего MyChildViewController
self
и внедрите его- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
в свой родительский контроллер представления. БУМ! У вас есть информация, переданная от ребенка до родителя. Отношения между этими двумя объектами даже не должны быть такими же тесными, как родитель / ребенок. Это контракт на обслуживание, так что пока объект, подписывающий соглашение, завершает сделку, внедряя необходимые методы, вы великолепны!ПРИМЕЧАНИЕ. Делегаты должны быть слабыми / назначать свойства, иначе вы войдете в цикл сохранения, где ни один объект не может быть освобожден.
Надеюсь это поможет!
источник
Делегаты - это объекты, которые реализуют определенные функции, когда не имеет смысла реализовывать эти функции в обычном объекте. Это форма внедрения зависимости.
Для конкретного примера посмотрите на протокол UITableViewDelegate. Эти методы не имеют смысла для непосредственного осуществления табличного представления, потому что действия для выбора строки табличного представления будут отличаться в каждом приложении и, возможно, в каждом табличном представлении. У делегата есть метод
-tableView:didSelectRowAtIndexPath:
, позволяющий создать объект, который обрабатывает выбор строки, не разбивая подклассы табличного представления для каждого отдельного действия, которое вы хотите реализовать.источник