2013-08-21 2 views
2

Всякий раз, когда я хотел сообщить что-либо родительскому классу, я использовал делегат вместо вызова непосредственно функций родителя. Я реализовал, как это ...Как вызов делегата отличается от обычного вызова метода?

например:

CustomClass *custom = [[CustomClass alloc] init]; 
    // assign delegate 
    custom.delegate = self; // Here we are giving parent instance like normal method call. 
    [custom helloDelegate]; 

В пользовательском классе, я намекал родитель, как показано ниже ....

-(void)helloDelegate 
{ 
    // send message the message to the delegate 
    [_delegate sayHello:self]; 
} 

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

Thanx

+2

Это способствует ослаблению связи –

+0

Это то же самое, если вы никогда не меняете своего делегата, все равно, если ваш делегат может быть более чем одним. – zneak

+0

Что вы подразумеваете под «сообщать что-то родительскому классу»? Если вы находитесь в производном классе, то сам производный класс является версией родительского класса. Хотя если вы хотите сообщить что-то родительскому классу, используйте [super methodName:]. – CodenameLambda1

ответ

0

Рабочий пример преимущества использования делегата в отличие от использования прямого отношения.

Скажите, что вы пишете универсальное приложение. У вас есть два контроллера вида в вашем коде iPadViewController и iPhoneViewController, и им необходимо получить данные из веб-службы. Таким образом, вы создаете класс для своего веб-сервиса, который вызывается webServiceDownloaderClass.

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

Ваши варианты здесь ...

Вариант 1 сильной связи

В вас iPadViewController вы определяете метод - (void)webServiceDidGetArray:(NSArray *)array;. И в iPhoneViewController вы определяете тот же метод.

Для того, чтобы webServiceDownloaderClass называть эти методы теперь необходима ссылка на каждый из контроллеров ...

@property (nonatomic, strong) IPadViewController *iPadController; 
@property (nonatomic, strong) IPhoneViewController *iPhoneController; 

, а затем, когда он закончит это необходимо, чтобы определить, какой из них назвать ...

if (iPadController) { 
    [iPadController webServiceDidGetArray]; 
} 

etc.... 

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

Вариант 2 Делегация

В своем классе услуги, которые мы вам определить протокол.

@protocol WebServiceDownloaderDelegate <NSObject> 

- (void)webServiceDidGetArray:(NSArray *)array 

@end 

и делегат ...

@property (nonatomic, weak) id <WebServiceDownloaderDelegate> delegate; 

Теперь вы определяете действия класса веб-службы в классе веб-службы. И вам нужна только одна ссылка на любой класс, который хочет быть делегатом. Кроме того, любой класс может быть делегатом. Итак, теперь как iPad, так и iPhone-контроллер может быть делегатом, и, согласовав протокол, они «обещают» класс веб-сервисов, что они реализуют требуемый метод - (void)webServiceDidGetArray:(NSArray *)array;.

Конечно, это только один случай, когда делегаты могут быть полезны.

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

2

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

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

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

0

Делегатский звонок не отличается от обычного вызова метода!

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

В Objective C делегаты обычно реализуются с использованием «протоколов», но это далеко не единственное использование протоколов. Цель C широко использует их для обеспечения общих интерфейсов между различными классами Cocoa.

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

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

Смежные вопросы