2014-09-13 5 views
2

Так что я много читал о разъяснениях делегатов и практиках, но я все еще не понимаю, у меня есть конкретные вопросы, и я хотел бы получить некоторые проницательные простые ответы.Мне нужно понять, почему делегирование в Objective-C так важно, что делает его особенным?

  1. Зачем использовать делегат над методом экземпляра? В UIAlertView почему бы просто не сделать – alertView:clickedButtonAtIndex: методом экземпляра, который будет вызываться на моем примере UIAlertView?

  2. Что является собственностью делегата? почему я должен сделать свойство делегата и определить его с этим странным синтаксисом @property (nonatomic, strong) id <ClassesDelegate> delegate

  3. Является ли делегат и протокол двумя лицами для монет?

  4. Когда я узнаю, что я должен реализовать делегат в своем приложении вместо прямого вызова?

  5. Является ли делегат таким же важным и важным в Swift?

  6. Что называется первым и почему? Метод в классе, который сделал себя делегатом? или метод делегата в классе, где он объявлен?

Спасибо, что нашли время, чтобы пройти через это, я отчаянно искал ясные и полезные ответы на мои вопросы, не стесняйтесь, чтобы дать пример или покрыть некоторую связанную тему!

+0

Делегирование шаблон проектирования. Он может быть реализован на любом языке. Это не относится к Objective-C. – rmaddy

+0

Делегирование замечательно, и делегаты не должны быть «сильными», они должны быть «слабыми». – quellish

+0

@maddy История предостережения: хотя это верно в 1993 году, были дискуссии о направлении C++ в основном между Cargile и Stroustrup (угадайте, кто выиграл) по двум основным вопросам. 1. Многократная последовательность 2. Делегирование. Cargile хотел, чтобы это был гражданин первого класса C++. Строуступ утверждал, что никогда не видел использования Делегации, которая не была ни игрушкой, ни запутанной, ни трудной для понимания. – zaph

ответ

3

Преимущество делегирования - инверсия зависимостей.

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

Существует стоимость: нам нужно установить делегат, а UITableview должен проверить во время выполнения, что метод делегата реализован.

Примечание: Когда я говорю UITableview, я включаю UITableviewDelegate и UITableviewDatasource.

См.: Dependency inversion principle и Clean Code, Episode 13.

+0

Я делаю все возможное, чтобы понять, что вы только что сказали. –

0
  1. Иногда вы хотите, чтобы ваш UIAlertView работал по-разному в разных контекстах. Если вы настроите свой пользовательский UIAlertView на делегирование, он должен предоставить все эти контексты (много операторов if/else). Вы также можете установить отдельный делегат для каждого контекста.
  2. Этот способ говорит вашему компилятору, что каждый класс (id), который реализует протокол ClassesDelegate, может быть установлен в это свойство. В качестве побочного примечания обычно должно быть weak вместо strong, чтобы не вводить ссылочный цикл (класс A содержит B, а B имеет A)
  3. Протокол (интерфейс на других языках) используется для определения набора методов, которые должны быть реализованы посредством класс. Если класс соответствует протоколу, вы можете вызвать эти методы без знания конкретного класса. Делегат - это шаблон, в котором класс A делегирует некоторую работу классу B (например,абстрактные делегаты принтера его работа в режиме реального принтера)
  4. Если вам нужно несколько различного поведения, которые зависят от контекста (например, ContactsViewController необходимо обновить свой список, когда загрузка закончена, но SingleContactViewController необходимо перезагрузить изображение, этикетка и т.д.)
  5. Это один из самых фундаментальных шаблонов в программировании, так что да.
  6. Это тот же самый метод
+0

Примечание: «методы, которые требуются». Но не все методы делегатов требуются при реализации Apple в шаблоне делегата. – zaph

+0

Благодарим вас, у вас есть некоторые кусочки непонятно, будет работать над этим больше. –

1

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

1) Подумайте об этом так: способ, которым UIAlertView работает сейчас, позволяет Apple «делегировать» реализацию alertView: clickedButtonAtIndex: вам. Если это был метод экземпляра UIAlertView, это будет одна и та же реализация для всех. Затем для настройки реализации потребуется подклассификация - зачастую это зависит от шаблона проектирования. Apple имеет тенденцию идти с составом над наследованием в своих рамках, и это пример этого. Вы можете узнать больше об этой концепции: http://en.wikipedia.org/wiki/Composition_over_inheritance

2) Свойство delegate является ссылкой на объект, который реализует методы делегирования, и которые должны использоваться для делегирования этих задач. Странный синтаксис просто означает это - свойство, которое содержит ссылку на объект, который придерживается протокола.

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

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

5) Абсолютно! Objective-C и Swift являются языками программирования, а шаблон делегирования является примером шаблона проектирования. В целом шаблоны проектирования представляют собой хозиональные концепции, которые выходят за пределы вертикалей языков программирования.

6) Я не уверен, что я вас точно понимаю, но я думаю, что в вопросе есть немного недоразумений - метод не вызывается дважды. Метод, объявленный в протоколе делегата, вызывается один раз - обычно из класса, который содержит свойство делегата. Класс призывает делегатов реализовать это свойство через что-то вроде:

[self.delegate someMethodThatMyDelegateImplemented];

Я надеюсь, что это помогло!

+0

Спасибо за ваше объяснение. Тем не менее, я все еще не уверен, получил ли я часть собственности делегата, можете ли вы попытаться объяснить это по-другому? –

+0

Кроме того, могу ли я использовать шаблон делегирования без протокола? как это будет выглядеть? –

+0

Почему я удалил делегата из своего заголовка, и приложение все еще работает, оно только предупреждает меня? почему я смог использовать метод протокола из класса делегата, не сказав, что я согласен с этим делегатом, и он работает? 'Присвоение 'id ' из несовместимого типа 'ViewController * const __strong'' –

0

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

Теперь предположим, что вы используете библиотеку, которая подклассифицирует UIAlertView, предоставляя больше возможностей. Это проблема, потому что теперь вам нужно подклассифицировать этот подкласс вместо UIAlertView.

Теперь предположим, что библиотека использует разные подклассы UIAlertview, в зависимости от того, запускаете ли вы iOS 7 или 8 и UIAlertview без изменений на iOS 6. У вас проблемы. Ваш шаблон подкласса разбивается.

Вместо этого вы создаете делегат, который выполняет все функции, специфичные для одного UIAlertview. Этот делегат будет отлично работать с библиотекой. Вместо подкласса огромного и сложного класса вы пишете очень простой класс. Скорее всего, код, использующий UIAlertview, точно знает, что должен делать делегат, поэтому вы можете сохранить этот код вместе.

+0

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

3

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

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

Сценарий № 1

Вы идете в свой кабинет, и дать ему необходимую ему информацию:

  • название компании
  • компания # номер/ID
  • номер сотрудников
  • адрес электронной почты
  • улица addres s
  • т.д.

Тогда бухгалтер будет хранить данные где-нибудь, и, вероятно, сказать вам «не забудьте позвонить мне, если есть какие-либо изменения».

Завтра вы нанимаете нового сотрудника, но забудьте уведомить своего бухгалтера. Он по-прежнему будет использовать оригинальные устаревшие данные, которые вы ему предоставили.

Сценарий № 2

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

Позже он позвонит вам и спросит: какое название?

Позже он позвонит вам и спросит: сколько у вас сотрудников?

Позже он позвонит вам и спросит: какой адрес вашей компании?

На следующий день после найма нового сотрудника.

Через 2 дня он позвонит вам с вопросом: сколько у вас есть сотрудника?

В модели делегирования (сценарий № 2) вы увидите, что ваш бухгалтер всегда будет получать по требованию современные данные, потому что он будет звонить вам каждый раз, когда ему нужны данные. Это то, что «не называй меня, я тебе позвоню» означает, когда речь идет об обращении контроля (с точки зрения бухгалтера).

Транспонирование, что в развитии, например, для заполнения таблицы у вас есть 2 варианта:

  • экземпляр таблицы управления, проходят все данные (список элементов для отображения), а затем задать таблицу, чтобы сделать себя
  • экземпляр элемента управления таблицы, дать ему указатель делегата, и пусть его называют делегат, когда он должен знать:
    • количество строк в таблице
    • данные для отображения на строке нет. n
    • высота строки нет. n должно иметь
    • и т.п. но также когда:
    • номер строки. п было выполнено постукивание
    • заголовок был постучал
    • т.д.
Смежные вопросы