2009-08-12 12 views
11

Ich bin nicht sicher über meine Terminologie hier, aber:Kann ein Objekt ein Delegat für mehrere Delegierer sein?

Ich habe einen ViewController in einer iPhone-App, die ein Delegat für zwei andere Objekte (Delegatoren) sein muss.

Ist das möglich? Dies funktioniert nicht:

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

Antwort

24

Der richtige Plural arbeiten ist Delegierten und ja, absolut, können Sie Ihre Klasse die Delegierten für unterschiedliche Protokolle haben.

Die Syntax ist jedoch wie folgt aus:

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

ich eine, die wie folgt aussieht:

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

} 

Mit freundlichen Grüßen,

3

Ihre Syntax ist nicht ganz richtig, aber es ist durchaus möglich, ein Objekt wirkt als Delegierter für mehrere Kunden zu haben.

Etwas wie:

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

... sollte

6

leicht pedantisch, aber wichtigen Unterschied: Was bieten Sie in Ihre Frage ist kein Objekt, das ein Delegierter mehrerer Delegierer ist, sondern ein Objekt, das mehreren Protokollen entspricht. In den meisten Fällen wird einem Delegat ein Protokoll zugeordnet (UIActionSheetDelegate, UITextFieldDelegate), aber nicht alle Delegaten verfügen über Protokolle, und nicht alle Protokolle implizieren Delegate.

In einem sehr konstruiertes Beispiel, könnten Sie ein Objekt haben, die Delegierten zu einem anderen Objekt, das keine Protokolle entspricht:

#import "ObjectB.h" 

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

// ... 

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

In diesem Beispiel Instanzen von ObjectA eine Instanz von ObjectB als „Delegierter“ erwarten , obwohl ObjectB nicht wirklich ein Protokoll, sondern eine Klassenschnittstelle ist! Die Existenz eines Objekts als Delegierter ist eher eine Geisteshaltung als eine strikte Anforderung, ein Protokoll zu haben - es ist nur so, dass die meisten (okay, fast alle) Entwickler die Delegiertenmethoden nehmen und sie in ein Protokoll aufteilen, so dass mehrere Objekte entstehen kann Delegaten für Instanzen von ObjectA werden, anstatt dass der Delegat eine Instanz (oder Unterklasse) von ObjectB sein muss. Dies beseitigt auch die Notwendigkeit, dass ObjectA ObjectB im Sinne von #import seiner Header-Datei "kennt".

In einem etwas weniger konstruierten Beispiel kann ein Objekt einem Protokoll entsprechen, ohne Delegat zu sein. Stellen Sie sich das NSCopying-Protokoll als gutes Beispiel vor - alles, was das Protokoll sagt, ist, dass Objekte, die es implementieren, mit der copy-Methode kopiert werden können. Leute betrachten copy eine "delegieren" -Methode nicht, da kein Objekt einfach [delegate copy] sagen wird, ohne dann etwas mit dieser Kopie zu tun, also sind Objekte, die NSCopying implementieren, nicht wirklich "delegieren" -Objekte.

Am Ende, denken Sie daran: ein Protokoll impliziert nicht einen Delegaten, und ein Delegat bedeutet nicht immer (aber normalerweise) ein Protokoll.

+1

Natürlich werden auch informelle Protokolle für Delegaten häufig verwendet, wenn Sie nicht explizit die Methoden als Protokoll erforderlich sind, aber die Methodennamen kennen sollen. UIKit und AppKit verwenden häufig informelle Protokolle und verhalten sich nur dann fehlerfrei, wenn die Klasse die vom Protokoll benötigte Nachricht nicht unterstützt. – AlBlue

+0

AlBlue: guter Punkt! Ein Beispiel, das mir einfällt, ist NSXMLParser, das kein entsprechendes formales Protokoll NSXMLParserDelegate besitzt, aber eine Handvoll 'parser: did ...:' Methoden dokumentiert. – Tim

2

Zusätzlich zu dem, was zum Implementieren mehrerer Delegatprotokolle gesagt wurde, macht das Delegierungsmuster von Cocoa es für ein Objekt einfach, ein Delegat für mehrere Objekte des gleichen Typs zu werden. Aus diesem Grund enthalten die meisten Delegate-Methoden einen Zeiger auf das aufrufende Objekt als Parameter oder als Objekt einer NSNotification. Sie können damit mehr Informationen über das Objekt erhalten oder es mit einer Instanzvariablen vergleichen, um herauszufinden, welche Aktion ausgeführt werden soll.

Verwandte Themen