Может ли объект быть делегатом для нескольких делегатов?

Я не уверен в моей терминологии здесь, но:

У меня есть приложение ViewController в приложении iPhone, которое должно быть делегатом для двух других объектов (делегатов).

Возможно ли это? Это не работает:

@interface my_projectViewController : UIViewController <DelegatorOne> <DelegatorTwo> {
  ...
}

Ответ 1

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

Синтаксис, однако, выглядит следующим образом:

@interface my_projectViewController : UIViewController <DelegatorOne, DelegatorTwo> {
  ...
}

У меня есть тот, который выглядит так:

@interface MyViewController : UIViewController<UITextFieldDelegate,UIWebViewDelegate,UINavigationBarDelegate,UIActionSheetDelegate,URLDownloaderDelegate> {

}

С уважением,

Ответ 2

Слегка педантичная, но важная разница: то, что вы предоставляете в своем вопросе, не является объектом, являющимся делегатом нескольких делегатов, а вместо этого объектом, соответствующим нескольким протоколам. В большинстве случаев у делегата будет связанный с ним протокол (UIActionSheetDelegate, UITextFieldDelegate), но не все делегаты имеют протоколы, а не все протоколы подразумевают делегатов.

В очень надуманном примере у вас может быть объект, который делегирует другому объекту, который не соответствует никаким протоколам:

#import "ObjectB.h"

@interface ObjectA : NSObject {
    ObjectB *delegate;
}
@end

// ...

@interface ObjectB : NSObject { }
 - (void)delegateMethod;
@end

В этом примере экземпляры ObjectA ожидают, что экземпляр ObjectB станет их "делегатом", хотя ObjectB на самом деле не является протоколом, а интерфейсом класса! Существование объекта в качестве делегата - это скорее настроение, чем строгое требование о протоколе, - это то, что большинство (нормально, почти всех) разработчиков будут принимать методы делегата и разбивать их на протокол, чтобы несколько объектов могут стать делегатами для экземпляров ObjectA, а не требовать, чтобы делегат был экземпляром (или подклассом) ObjectB. Это также устраняет необходимость в ObjectA "знать об" ObjectB в смысле #import с его заголовочным файлом.

В немного менее надуманном примере объект может соответствовать протоколу, не являясь делегатом. Подумайте о протоколе NSCopying в качестве отличного примера этого - все, что говорит протокол, - это объекты, которые его реализуют, можно скопировать с помощью метода copy. Люди не рассматривают copy метод "делегировать", поскольку ни один объект не собирается говорить [delegate copy], не делая что-то с этой копией, поэтому объекты, реализующие NSCopying, на самом деле не являются "делегированными" объектами.

В конце, просто запомните: протокол не подразумевает делегата, а делегат не всегда (но обычно делает) подразумевает протокол.

Ответ 3

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

Что-то вроде:

@interface MyViewController: UIViewController <protocol1, protocol2> 
{
}
@end

... должен работать

Ответ 4

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