Ein Objective-C-Delegat ist ein Objekt, dem der delegateEigenschaft ein anderes Objekt zugewiesen wurde . Um eine zu erstellen, definieren Sie eine Klasse, die die Delegatenmethoden implementiert, an denen Sie interessiert sind, und markieren diese Klasse als Implementierung des Delegatenprotokolls.
Angenommen, Sie haben eine UIWebView. Wenn Sie die webViewDidStartLoad:Methode des Delegaten implementieren möchten , können Sie eine Klasse wie die folgende erstellen:
Auf der UIWebViewSeite, hat es wahrscheinlich Code ähnlich wie diese zu sehen , ob die Delegierten reagieren auf die webViewDidStartLoad:Nachricht mit respondsToSelector:ihm gegebenenfalls und senden.
Die Delegate-Eigenschaft selbst wird normalerweise weak(in ARC) oder assign(vor ARC) deklariert , um Aufbewahrungsschleifen zu vermeiden, da der Delegat eines Objekts häufig einen starken Verweis auf dieses Objekt enthält. (Beispielsweise ist ein Ansichtscontroller häufig der Delegat einer darin enthaltenen Ansicht.)
Delegierte für Ihre Klassen machen
Um Ihre eigenen Delegaten zu definieren, müssen Sie ihre Methoden irgendwo deklarieren, wie in den Apple Docs zu Protokollen beschrieben . Normalerweise deklarieren Sie ein formelles Protokoll. Die von UIWebView.h umschriebene Deklaration würde folgendermaßen aussehen:
@protocolUIWebViewDelegate<NSObject>@optional-(void)webViewDidStartLoad:(UIWebView*)webView;// ... other methods here@end
Dies ist analog zu einer Schnittstelle oder einer abstrakten Basisklasse, da UIWebViewDelegatein diesem Fall ein spezieller Typ für Ihren Delegaten erstellt wird. Delegierte Implementierer müssten dieses Protokoll übernehmen:
@interfaceMyClass<UIWebViewDelegate>// ...@end
Und dann implementieren Sie die Methoden im Protokoll. Bei Methoden, die im Protokoll als @optional(wie die meisten delegierten Methoden) deklariert sind , müssen Sie dies überprüfen, -respondsToSelector:bevor Sie eine bestimmte Methode aufrufen.
Benennung
Delegierungsmethoden werden normalerweise beginnend mit dem Namen der delegierenden Klasse benannt und nehmen das delegierende Objekt als ersten Parameter. Sie verwenden auch oft eine Willens-, Soll- oder Did-Form. Also webViewDidStartLoad:(erster Parameter ist die Webansicht) anstatt loadStarted(ohne Parameter) zum Beispiel.
Geschwindigkeitsoptimierungen
Anstatt jedes Mal zu überprüfen, ob ein Delegat auf einen Selektor antwortet, wenn wir ihm eine Nachricht senden möchten, können Sie diese Informationen zwischenspeichern, wenn Delegierte festgelegt werden. Eine sehr saubere Möglichkeit, dies zu tun, besteht darin, ein Bitfeld wie folgt zu verwenden:
Dann können wir im Hauptteil überprüfen, ob unser Delegat Nachrichten verarbeitet, indem wir auf unsere delegateRespondsToStruktur zugreifen -respondsToSelector:und nicht immer wieder senden .
Informelle Delegierte
Vor Protokolle gab, war es üblich , eine verwenden Kategorie auf , NSObjectum die Verfahren zu erklären Delegierter implementieren könnte. Zum Beispiel CALayertut dies immer noch:
@interfaceNSObject(CALayerDelegate)-(void)displayLayer:(CALayer*)layer;// ... other methods here@end
Dies teilt dem Compiler mit, dass ein Objekt implementiert werden kann displayLayer:.
Sie würden dann den gleichen -respondsToSelector:Ansatz wie oben beschrieben verwenden, um diese Methode aufzurufen. Delegaten implementieren diese Methode und weisen die delegateEigenschaft zu, und das war's (es gibt keine Erklärung, dass Sie einem Protokoll entsprechen). Diese Methode ist in Apples Bibliotheken üblich, aber neuer Code sollte den oben beschriebenen moderneren Protokollansatz verwenden, da dieser Ansatz die Umweltverschmutzung verschmutzt NSObject(was die automatische Vervollständigung weniger nützlich macht) und es dem Compiler erschwert, Sie vor Tippfehlern und ähnlichen Fehlern zu warnen.
Ich denke, Sie müssen den unsigned intTyp umwandeln, BOOLda der Rückgabewert von delegate respondsToSelectorvom Typ ist BOOL.
Roland
Kann der Delegat wie in C ++ für den Polymorphismus verwendet werden?
@ Dan Ja, sicher. Protokolle werden im Allgemeinen für den Polymorphismus verwendet.
Jesse Rusak
@ JesseRusak Ich denke, "JSSomethingDelegate" sollte aus Gründen der Konsistenz "SomethingDelegate" sein :)
Hans Knöchel
382
Die genehmigte Antwort ist großartig, aber wenn Sie nach einer 1-minütigen Antwort suchen, versuchen Sie Folgendes:
Die Datei MyClass.h sollte folgendermaßen aussehen (Delegatenzeilen mit Kommentaren hinzufügen!)
#import <BlaClass/BlaClass.h>@classMyClass;//define class, so protocol can see MyClass@protocolMyClassDelegate<NSObject>//define delegate protocol-(void) myClassDelegateMethod:(MyClass*) sender;//define delegate method to be implemented within another class@end//end protocol@interfaceMyClass:NSObject{}@property(nonatomic, weak) id <MyClassDelegate>delegate;//define MyClassDelegate as delegate@end
Die Datei MyClass.m sollte so aussehen
#import "MyClass.h"@implementationMyClass@synthesizedelegate;//synthesise MyClassDelegate delegate-(void) myMethodToDoStuff {[self.delegate myClassDelegateMethod:self];//this will call the method implemented in your other class }@end
So verwenden Sie Ihren Delegaten in einer anderen Klasse (in diesem Fall UIViewController MyVC) MyVC.h:
#import "MyClass.h"@interfaceMyVC:UIViewController<MyClassDelegate>{//make it a delegate for MyClassDelegate}
MyVC.m:
myClass.delegate= self;//set its delegate to self somewhere
Implementieren Sie die Delegate-Methode
-(void) myClassDelegateMethod:(MyClass*) sender {NSLog(@"Delegates are great!");}
Es ist großartig, diese Antwort als Kurzreferenz zu verwenden. Aber warum ist die Delegate-Eigenschaft in Ihrer MyClass.h als "IBOutlet" markiert?
Arno van der Meer
4
@ArnovanderMeer Guter Fang! Ich kann mich nicht erinnern warum. Ich brauche es in meinem Projekt, aber nicht in diesem Beispiel, ich habe es entfernt. thx
Tibidabo
Vielen Dank. So nett und gründlich die akzeptierte Antwort auch ist, ich lerne am besten aus einem kompakten Beispielcode. Es ist gut, zwei Antworten zu haben.
Sudo
@ Tibidabo Total hervorragend. Ich wünschte wirklich, jeder könnte solche Programmierkonzepte erklären. Ich habe im Laufe der Jahre Hunderte von Erklärungen über "Delegierte" gesehen und diese Theorie bis jetzt nie wirklich verstanden! Vielen Dank ...
Charles Robertson
5
Wo wird myClassin MyVC.m instanziiert?
Lane Rettig
18
Bei Verwendung der formalen Protokollmethode zum Erstellen der Delegatenunterstützung habe ich festgestellt, dass Sie eine ordnungsgemäße Typprüfung (allerdings Laufzeit, keine Kompilierungszeit) sicherstellen können, indem Sie Folgendes hinzufügen:
if(![delegate conformsToProtocol:@protocol(MyDelegate)]){[NSException raise:@"MyDelegate Exception"
format:@"Parameter does not conform to MyDelegate protocol at line %d",(int)__LINE__];}
in Ihrem Delegate Accessor (setDelegate) Code. Dies hilft, Fehler zu minimieren.
Vielleicht entspricht dies eher dem, was Sie vermissen:
Wenn Sie aus einer C ++ - Perspektive kommen, sind die Delegierten etwas gewöhnungsbedürftig - aber im Grunde funktionieren sie einfach.
So funktioniert es: Sie legen ein Objekt fest, das Sie als Delegat an NSWindow geschrieben haben, aber Ihr Objekt verfügt nur über Implementierungen (Methoden) für eine oder einige der vielen möglichen Delegatmethoden. Es passiert also etwas und Sie NSWindowmöchten Ihr Objekt aufrufen. Es verwendet lediglich die respondsToSelectorMethode von Objective-c, um zu bestimmen, ob Ihr Objekt diese Methode aufrufen möchte, und ruft sie dann auf. So funktioniert Objective-C - Methoden werden bei Bedarf nachgeschlagen.
Es ist völlig trivial, dies mit Ihren eigenen Objekten zu tun, es ist nichts Besonderes los, Sie könnten zum Beispiel eines NSArrayvon 27 Objekten haben, alle verschiedene Arten von Objekten, nur 18 von ihnen haben die Methode -(void)setToBue;Die anderen 9 nicht. Also, um setToBluealle 18 anzurufen , die es tun müssen, so etwas:
for(id anObject in myArray){if([anObject respondsToSelector:@selector(@"setToBlue")])[anObject setToBlue];}
Das andere an Delegaten ist, dass sie nicht beibehalten werden, sodass Sie den Delegaten nilin Ihrer MyClass deallocMethode immer festlegen müssen .
Als von Apple empfohlene bewährte Methode empfiehlt es sich, dass der Delegierte (der per Definition ein Protokoll ist) dem NSObjectProtokoll entspricht.
@protocolMyDelegate<NSObject>...@end
& Um optionale Methoden in Ihrem Delegaten zu erstellen (dh Methoden, die nicht unbedingt implementiert werden müssen), können Sie die @optionalAnnotation wie folgt verwenden:
@protocolMyDelegate<NSObject>......// Declaration for Methods that 'must' be implemented'......@optional...// Declaration for Methods that 'need not necessarily' be implemented by the class conforming to your delegate...@end
Wenn Sie also Methoden verwenden, die Sie als optional angegeben haben, müssen Sie (in Ihrer Klasse) überprüfen, respondsToSelectorob die Ansicht (die Ihrem Delegaten entspricht) Ihre optionalen Methoden tatsächlich implementiert hat oder nicht.
Ich denke, all diese Antworten sind sehr sinnvoll, wenn Sie die Delegierten verstehen. Persönlich kam ich aus dem Land von C / C ++ und davor aus prozeduralen Sprachen wie Fortran usw. Hier ist meine 2-minütige Darstellung ähnlicher Analoga im C ++ - Paradigma.
Wenn ich einem C ++ / Java-Programmierer die Delegierten erklären würde, würde ich sagen
Was sind Delegierte? Dies sind statische Zeiger auf Klassen innerhalb einer anderen Klasse. Sobald Sie einen Zeiger zugewiesen haben, können Sie Funktionen / Methoden in dieser Klasse aufrufen. Daher werden einige Funktionen Ihrer Klasse an eine andere Klasse "delegiert" (in C ++ world - Zeiger auf durch einen Klassenobjektzeiger).
Was sind Protokolle? Konzeptionell dient es einem ähnlichen Zweck wie die Header-Datei der Klasse, die Sie als Delegatenklasse zuweisen. Ein Protokoll ist eine explizite Methode, um zu definieren, welche Methoden in der Klasse implementiert werden müssen, deren Zeiger als Delegat innerhalb einer Klasse festgelegt wurde.
Wie kann ich in C ++ etwas Ähnliches tun? Wenn Sie dies in C ++ versuchen würden, würden Sie Zeiger auf Klassen (Objekte) in der Klassendefinition definieren und diese dann mit anderen Klassen verbinden, die zusätzliche Funktionen als Delegaten für Ihre Basisklasse bereitstellen. Diese Verkabelung muss jedoch im Code enthalten sein und ist ungeschickt und fehleranfällig. Ziel C geht lediglich davon aus, dass Programmierer diese Disziplin nicht am besten einhalten können, und bietet Compiler-Einschränkungen, um eine saubere Implementierung durchzusetzen.
Sie sprechen von Semantik, während ich über die Intuition sprach. Sie sprechen von einer virtuellen Funktion - aber es kann schwierig sein, sich an die neue Terminologie zu gewöhnen. Die Antwort
richtet sich
Was Sie sagen, ist mir nicht wirklich klar. Warum schreibst du keine neue Antwort und lässt uns sehen, ob mehr Leute sie nützlich finden, sie werden darüber abstimmen?
DrBug
9
Schnelle Version
Ein Delegat ist nur eine Klasse, die für eine andere Klasse arbeitet. Lesen Sie den folgenden Code für ein etwas albernes (aber hoffentlich aufschlussreiches) Spielplatzbeispiel, das zeigt, wie dies in Swift gemacht wird.
// A protocol is just a list of methods (and/or properties) that must// be used by any class that adopts the protocol.
protocol OlderSiblingDelegate:class{// This protocol only defines one required method
func getYourNiceOlderSiblingAGlassOfWater()->String}classBossyBigBrother{// The delegate is the BossyBigBrother's slave. This position can // be assigned later to whoever is available (and conforms to the // protocol).
weak var delegate:OlderSiblingDelegate?
func tellSomebodyToGetMeSomeWater()->String?{// The delegate is optional because there might not be anyone// nearby to boss around.returndelegate?.getYourNiceOlderSiblingAGlassOfWater()}}// PoorLittleSister conforms to the OlderSiblingDelegate protocolclassPoorLittleSister:OlderSiblingDelegate{// This method is repquired by the protocol, but the protocol said// nothing about how it needs to be implemented.
func getYourNiceOlderSiblingAGlassOfWater()->String{return"Go get it yourself!"}}// initialize the classes
let bigBro =BossyBigBrother()
let lilSis =PoorLittleSister()// Set the delegate // bigBro could boss around anyone who conforms to the // OlderSiblingDelegate protocol, but since lilSis is here, // she is the unlucky choice.
bigBro.delegate= lilSis
// Because the delegate is set, there is a class to do bigBro's work for him.// bigBro tells lilSis to get him some water.if let replyFromLilSis = bigBro.tellSomebodyToGetMeSomeWater(){
print(replyFromLilSis)// "Go get it yourself!"}
In der Praxis werden Delegierte häufig in den folgenden Situationen eingesetzt
Wenn eine Klasse Informationen an eine andere Klasse weitergeben muss
Wenn eine Klasse einer anderen Klasse erlauben möchte, sie anzupassen
Die Klassen müssen vorher nichts voneinander wissen, außer dass die Delegatenklasse dem erforderlichen Protokoll entspricht.
Ich empfehle dringend, die folgenden zwei Artikel zu lesen. Sie haben mir geholfen, die Delegierten noch besser zu verstehen als die Dokumentation .
Ok, dies ist nicht wirklich eine Antwort auf die Frage, aber wenn Sie nachschlagen, wie Sie Ihren eigenen Delegierten bilden können, könnte etwas viel Einfacheres eine bessere Antwort für Sie sein.
Ich setze meine Delegierten kaum um, weil ich sie selten brauche. Ich kann NUR EINEN Delegierten für ein Delegatenobjekt haben. Wenn Sie also möchten, dass Ihr Delegierter in eine Richtung kommuniziert / Daten weitergibt, sind Sie mit Benachrichtigungen viel besser dran.
NSNotification kann Objekte an mehr als einen Empfänger übergeben und ist sehr einfach zu verwenden. Es funktioniert so:
Die Datei MyClass.m sollte so aussehen
#import "MyClass.h"@implementationMyClass-(void) myMethodToDoStuff {//this will post a notification with myClassData (NSArray in this case) in its userInfo dict and self as an object[[NSNotificationCenter defaultCenter] postNotificationName:@"myClassUpdatedData"
object:self
userInfo:[NSDictionary dictionaryWithObject:selectedLocation[@"myClassData"] forKey:@"myClassData"]];}@end
So verwenden Sie Ihre Benachrichtigung in anderen Klassen: Fügen Sie eine Klasse als Beobachter hinzu:
-(void) otherClassUpdatedItsData:(NSNotification*)note {NSLog(@"*** Other class updated its data ***");MyClass*otherClass =[note object];//the object itself, you can call back any selector if you wantNSArray*otherClassData =[note userInfo][@"myClassData"];//get myClass data object and do whatever you want with it}
Vergessen Sie nicht, Ihre Klasse als Beobachter zu entfernen, wenn
Angenommen, Sie haben eine Klasse, die Sie entwickelt haben, und möchten eine Delegate-Eigenschaft deklarieren, um sie benachrichtigen zu können, wenn ein Ereignis eintritt:
Sie deklarieren also ein Protokoll in der MyClassHeader-Datei (oder einer separaten Header-Datei) und deklarieren die erforderlichen / optionalen Ereignishandler, die Ihr Delegat implementieren muss / sollte, und deklarieren dann eine Eigenschaft MyClassvom Typ ( id< MyClassDelegate>), was bedeutet, dass jede objektive c-Klasse konform ist Im Protokoll MyClassDelegatewerden Sie feststellen, dass die Delegate-Eigenschaft als schwach deklariert ist. Dies ist sehr wichtig, um den Aufbewahrungszyklus zu verhindern (meistens behält der Delegate dieMyClass Wenn Sie Instanz bei. Wenn Sie den Delegaten als Retain deklariert haben, behalten sich beide gegenseitig und keine von ihnen werden jemals veröffentlicht werden).
Sie werden auch feststellen, dass die Protokollmethoden die MyClassInstanz als Parameter an den Delegaten übergeben. Dies ist eine bewährte Methode für den Fall, dass der Delegat einige Methoden für eine MyClassInstanz aufrufen möchte, und hilft auch, wenn sich der Delegat MyClassDelegatefür mehrere MyClassInstanzen deklariert , z. B. wenn Sie mehrere haben UITableView'sInstanzen in Ihrem ViewControllerund erklärt sich als UITableViewDelegatezu allen von ihnen.
und in Ihrem MyClassbenachrichtigen Sie den Delegierten mit deklarierten Ereignissen wie folgt:
Sie überprüfen zunächst, ob Ihr Delegat auf die Protokollmethode reagiert, die Sie aufrufen möchten, falls der Delegat sie nicht implementiert und die App dann abstürzt (auch wenn die Protokollmethode erforderlich ist).
Hier ist eine einfache Methode zum Erstellen von Delegaten
Protokoll in .h-Datei erstellen. Stellen Sie sicher, dass dies vor dem Protokoll mit @class gefolgt vom Namen des UIViewControllers definiert ist< As the protocol I am going to use is UIViewController class>.
Schritt: 1: Erstellen Sie ein neues Klassenprotokoll mit dem Namen "YourViewController", das die Unterklasse der UIViewController-Klasse ist, und weisen Sie diese Klasse dem zweiten ViewController zu.
Schritt: 2: Gehen Sie zur Datei "YourViewController" und ändern Sie sie wie folgt:
#import <UIKit/UIkit.h>@classYourViewController;@protocolYourViewControllerDelegate<NSObject>@optional-(void)defineDelegateMethodName:(YourViewController*) controller;@required-(BOOL)delegateMethodReturningBool:(YourViewController*) controller;@end@interfaceYourViewController:UIViewController//Since the property for the protocol could be of any class, then it will be marked as a type of id.@property(nonatomic, weak) id<YourViewControllerDelegate>delegate;@end
Die im Protokollverhalten definierten Methoden können mit @optional und @required als Teil der Protokolldefinition gesteuert werden.
Schritt: 3: Implementierung des Delegierten
#import "delegate.h"@interfaceYourDelegateUser()<YourViewControllerDelegate>@end@implementationYourDelegateUser-(void) variousFoo {YourViewController*controller =[[YourViewController alloc] init];
controller.delegate= self;}-(void)defineDelegateMethodName:(YourViewController*) controller {// handle the delegate being called here}-(BOOL)delegateMethodReturningBool:(YourViewController*) controller {// handle the delegate being called herereturn YES;}@end
// teste, ob die Methode definiert wurde, bevor du sie aufrufst
Um Ihren eigenen Delegaten zu erstellen, müssen Sie zunächst ein Protokoll erstellen und die erforderlichen Methoden deklarieren, ohne sie zu implementieren. Implementieren Sie dieses Protokoll dann in Ihre Header-Klasse, in der Sie den Delegaten oder die Delegatmethoden implementieren möchten.
Dies ist die Serviceklasse, in der eine Aufgabe ausgeführt werden sollte. Es zeigt, wie Sie einen Delegaten definieren und wie Sie den Delegaten festlegen. In der Implementierungsklasse werden nach Abschluss der Aufgabe die Methoden des Delegaten aufgerufen.
Dies ist die Hauptansichtsklasse, von der aus die Serviceklasse aufgerufen wird, indem der Delegat auf sich selbst gesetzt wird. Außerdem ist das Protokoll in der Header-Klasse implementiert.
Das war's, und durch die Implementierung von Delegate-Methoden in dieser Klasse wird die Steuerung wieder hergestellt, sobald die Operation / Aufgabe abgeschlossen ist.
Haftungsausschluss: Dies ist die SwiftVersion zum Erstellen eines delegate.
Was sind Delegierte? … In der Softwareentwicklung gibt es allgemeine wiederverwendbare Lösungsarchitekturen, die dazu beitragen, häufig auftretende Probleme in einem bestimmten Kontext zu lösen. Diese „Vorlagen“ werden sozusagen am besten als Entwurfsmuster bezeichnet. Delegaten sind ein Entwurfsmuster, mit dem ein Objekt Nachrichten an ein anderes Objekt senden kann, wenn ein bestimmtes Ereignis eintritt. Stellen Sie sich vor, ein Objekt A ruft ein Objekt B auf, um eine Aktion auszuführen. Sobald die Aktion abgeschlossen ist, sollte Objekt A wissen, dass B die Aufgabe abgeschlossen hat, und die erforderlichen Maßnahmen ergreifen. Dies kann mit Hilfe von Delegierten erreicht werden!
Sie können eine App mit zwei Klassen sehen, ViewController Aund ViewController B. B hat zwei Ansichten, die beim Tippen die Hintergrundfarbe von ändern ViewController, nichts zu kompliziert, oder? Nun wollen wir auf einfache Weise darüber nachdenken, auch die Hintergrundfarbe von Klasse A zu ändern, wenn auf die Ansichten von Klasse B getippt wird.
Das Problem ist, dass diese Ansichten Teil der Klasse B sind und keine Ahnung von Klasse A haben. Daher müssen wir einen Weg finden, um zwischen diesen beiden Klassen zu kommunizieren, und hier erstrahlt die Delegation. Ich habe die Implementierung in 6 Schritte unterteilt, damit Sie diese bei Bedarf als Spickzettel verwenden können.
Schritt 1: Suchen Sie in der ClassBVC-Datei nach der Pragma-Markierung Schritt 1 und fügen Sie diese hinzu
Der erste Schritt besteht darin, ein protocolProtokoll zu erstellen . In diesem Fall erstellen wir das Protokoll in Klasse B. Innerhalb des Protokolls können Sie so viele Funktionen erstellen, wie Sie möchten, basierend auf den Anforderungen Ihrer Implementierung. In diesem Fall haben wir nur eine einfache Funktion, die ein optionales UIColorArgument akzeptiert . delegateIn diesem Fall empfiehlt es sich, Ihre Protokolle zu benennen, indem Sie das Wort am Ende des Klassennamens hinzufügen ClassBVCDelegate.
Schritt 2: Suchen Sie nach der Pragma-Markierung in Schritt 2 ClassVBCund fügen Sie diese hinzu
//MARK: step 2 Create a delegate property here.
weak var delegate:ClassBVCDelegate?
Hier erstellen wir nur eine Delegate-Eigenschaft für die Klasse. Diese Eigenschaft muss den protocolTyp übernehmen und sollte optional sein. Außerdem sollten Sie das schwache Schlüsselwort vor der Eigenschaft hinzufügen, um Speicherzyklen und potenzielle Speicherverluste zu vermeiden. Wenn Sie nicht wissen, was dies bedeutet, machen Sie sich vorerst keine Sorgen. Denken Sie daran, dieses Schlüsselwort hinzuzufügen.
Schritt 3: Suchen Sie nach der Pragma-Markierung Schritt 3 im handleTap methodin ClassBVCund fügen Sie diese hinzu
//MARK: step 3 Add the delegate method call here.delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)
Eine Sache, die Sie wissen sollten, führen Sie die App aus und tippen Sie auf eine Ansicht. Sie werden kein neues Verhalten sehen und das ist richtig, aber ich möchte darauf hinweisen, dass die App nicht abstürzt, wenn der Delegat aufgerufen wird, und Das liegt daran, dass wir es als optionalen Wert erstellen und es deshalb nicht abstürzt, selbst wenn der Delegierte noch nicht existiert. Gehen wir jetzt zur ClassAVCAkte und machen es, der Delegierte.
Schritt 4: Suchen Sie in der handleTap-Methode in nach der Pragma-Markierung Schritt 4 ClassAVC und fügen Sie diese wie neben Ihren Klassentyp ein.
//MARK: step 4 conform the protocol here.classClassAVC:UIViewController,ClassBVCDelegate{}
Jetzt hat ClassAVC die ClassBVCDelegate Protokoll übernommen hat, können Sie sehen, dass Ihr Compiler Ihnen einen Fehler mit der Meldung "Typ" ClassAVC entspricht nicht dem Protokoll "ClassBVCDelegate" anzeigt. Dies bedeutet nur, dass Sie die Methoden des Protokolls noch nicht verwendet haben. Stellen Sie sich das vor Wenn Klasse A das Protokoll annimmt, ist das wie das Unterzeichnen eines Vertrags mit Klasse B und dieser Vertrag besagt: "Jede Klasse, die mich adoptiert, MUSS meine Funktionen nutzen!"
Kurzer Hinweis: Wenn Sie aus einem Objective-CHintergrund stammen, denken Sie wahrscheinlich, dass Sie diesen Fehler auch beenden können, indem Sie diese Methode optional machen. Zu meiner und wahrscheinlich Ihrer Überraschung wird die SwiftSprache jedoch nicht optional protocolsunterstützt. Wenn Sie dies möchten, können Sie sie erstellen eine Erweiterung für Ihreprotocol oder verwenden Sie das Schlüsselwort @objc in Ihrer protocolImplementierung.
Persönlich, wenn ich ein Protokoll mit verschiedenen optionalen Methoden erstellen muss, würde ich es vorziehen, es in verschiedene zu unterteilen protocols. Auf diese Weise folge ich dem Konzept, meinen Objekten eine einzige Verantwortung zu übertragen, aber es kann je nach spezifischer Implementierung variieren.
hier ist ein guter Artikel über optionale Methoden.
Schritt 5: Suchen Sie nach der Pragma-Markierung Schritt 5 in der Methode zur Vorbereitung auf den Übergang und fügen Sie diese hinzu
//MARK: step 5 create a reference of Class B and bind them through the `prepareforsegue` method.if let nav = segue.destination as?UINavigationController, let classBVC = nav.topViewController as?ClassBVC{
classBVC.delegate= self
}
Hier erstellen wir nur eine Instanz von ClassBVCund weisen ihren Delegierten dem Selbst zu, aber was ist das Selbst hier? Nun, Selbst ist das, ClassAVCwas delegiert wurde!
Schritt 6: Suchen Sie abschließend nach dem Pragma in Schritt 6 ClassAVCund verwenden Sie die Funktionen von protocol, beginnen Sie mit der Eingabe von func changeBackgroundColor, und Sie werden sehen, dass es automatisch für Sie vervollständigt wird. Sie können eine beliebige Implementierung hinzufügen. In diesem Beispiel ändern wir nur die Hintergrundfarbe und fügen diese hinzu.
//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color:UIColor?){
view.backgroundColor = color
}
Führen Sie jetzt die App aus!
Delegatessind überall und Sie verwenden sie wahrscheinlich ohne Vorankündigung. Wenn Sie eine tableviewin der Vergangenheit verwendete Delegation erstellen , lösen viele Klassen von UIKITArbeiten um sie herum und viele andere frameworksdiese Hauptprobleme.
Vermeiden Sie eine enge Kopplung von Gegenständen.
Ändern Sie Verhalten und Erscheinungsbild, ohne dass Objekte in Unterklassen unterteilt werden müssen.
Ermöglichen, dass Aufgaben für ein beliebiges Objekt ausgeführt werden.
Herzlichen Glückwunsch, Sie implementieren gerade einen benutzerdefinierten Delegaten. Ich weiß, dass Sie wahrscheinlich denken, so viel Ärger nur dafür? Nun, Delegation ist ein sehr wichtiges Entwurfsmuster, um zu verstehen, ob Sie ein werden möchteniOS Entwickler werden , und denken Sie immer daran, dass sie eine Eins-zu-Eins-Beziehung zwischen Objekten haben.
Die Antwort wird tatsächlich beantwortet, aber ich möchte Ihnen einen "Spickzettel" zum Erstellen eines Delegaten geben:
DELEGATE SCRIPT
CLASS A -Wheredelegate is calling function
@protocol<#ProtocolName#> <NSObject>-(void)delegateMethod;@end@interface<#SomeViewController#> : <#UIViewController#> @property(nonatomic, assign) id <<#ProtocolName#>> delegate;@end@implementation<#SomeViewController#> -(void)someMethod {[self.delegate methodName];}@end
CLASS B -Wheredelegate is called
@interface<#OtherViewController#> (<#Delegate Name#>) {}@end@implementation<#OtherViewController#> -(void)otherMethod {
CLASSA *classA =[[CLASSA alloc] init];[classA setDelegate:self];}-delegateMethod(){}@end
Hier sind alle für die benutzerdefinierte Delegatenklasse festgelegt. Danach können Sie diese Delegatenmethode verwenden, wo Sie möchten. Zum Beispiel ...
in meinem anderen viewcontroller danach importieren
Erstellen Sie eine Aktion zum Aufrufen dieser Delegatenmethode
-(void)dropDownDidSelectItemWithString:(NSString*)itemString DropDownType:(DropDownType)dropDownType {switch(dropDownType){case DDCITY:{if(itemString.length >0){//Here i am printing the selected row[self.dropDownBtn1 setTitle:itemString forState:UIControlStateNormal];}}break;case DDSTATE:{//Here i am printing the selected row[self.dropDownBtn2 setTitle:itemString forState:UIControlStateNormal];}default:break;}}
//1.//Custom delegate @protocol TB_RemovedUserCellTag <NSObject>-(void)didRemoveCellWithTag:(NSInteger)tag;@end//2.//Create a weak reference in a class where you declared the delegate@property(weak,nonatomic)id <TB_RemovedUserCellTag> removedCellTagDelegate;//3. // use it in the class[self.removedCellTagDelegate didRemoveCellWithTag:self.tag];//4. import the header file in the class where you want to conform to the protocol@interfaceMyClassUsesDelegate()<TB_RemovedUserCellTag>@end
// 5. Implementieren Sie die Methode in der Klasse .m - (void) didRemoveCellWithTag: (NSInteger) tag {NSLog @ ("Tag% d", tag);
Beginnen wir mit einem Beispiel: Wenn wir ein Produkt online kaufen, durchläuft es einen Prozess wie Versand / Lieferung, der von verschiedenen Teams abgewickelt wird. Wenn der Versand abgeschlossen ist, sollte das Versandteam das Lieferteam benachrichtigen und es sollte eine Eins-zu-Eins-Kommunikation sein, um diese Informationen zu senden Dies wäre ein Overhead für andere Personen / Anbieter, die diese Informationen möglicherweise nur an erforderliche Personen weitergeben möchten.
Wenn wir also in Bezug auf unsere App denken, kann eine Veranstaltung eine Online-Bestellung sein und verschiedene Teams können wie mehrere Ansichten sein.
Hier ist der Code, der ShippingView als Versandteam und DeliveryView als Lieferteam betrachtet:
//Declare the protocol with functions having info which needs to be communicated
protocol ShippingDelegate:class{
func productShipped(productID :String)}//shippingView which shows shipping status of productsclassShippingView:UIView{
weak var delegate:ShippingDelegate?
var productID :String@IBAction func checkShippingStatus(sender:UIButton){// if product is shippeddelegate?.productShipped(productID: productID)}}//Delivery view which shows delivery status & tracking infoclassDeliveryView:UIView,ShippingDelegate{
func productShipped(productID :String){// update status on view & perform delivery}}//Main page on app which has both views & shows updated info on product whole statusclassProductViewController:UIViewController{
var shippingView :ShippingView
var deliveryView :DeliveryView
override func viewDidLoad(){
super.viewDidLoad()// as we want to update shipping info on delivery view, so assign delegate to delivery object// whenever shipping status gets updated it will call productShipped method in DeliveryView & update UI.
shippingView.delegate= deliveryView
//}}
Antworten:
Ein Objective-C-Delegat ist ein Objekt, dem der
delegate
Eigenschaft ein anderes Objekt zugewiesen wurde . Um eine zu erstellen, definieren Sie eine Klasse, die die Delegatenmethoden implementiert, an denen Sie interessiert sind, und markieren diese Klasse als Implementierung des Delegatenprotokolls.Angenommen, Sie haben eine
UIWebView
. Wenn Sie diewebViewDidStartLoad:
Methode des Delegaten implementieren möchten , können Sie eine Klasse wie die folgende erstellen:Anschließend können Sie eine Instanz von MyClass erstellen und als Delegat der Webansicht zuweisen:
Auf der
UIWebView
Seite, hat es wahrscheinlich Code ähnlich wie diese zu sehen , ob die Delegierten reagieren auf diewebViewDidStartLoad:
Nachricht mitrespondsToSelector:
ihm gegebenenfalls und senden.Die Delegate-Eigenschaft selbst wird normalerweise
weak
(in ARC) oderassign
(vor ARC) deklariert , um Aufbewahrungsschleifen zu vermeiden, da der Delegat eines Objekts häufig einen starken Verweis auf dieses Objekt enthält. (Beispielsweise ist ein Ansichtscontroller häufig der Delegat einer darin enthaltenen Ansicht.)Delegierte für Ihre Klassen machen
Um Ihre eigenen Delegaten zu definieren, müssen Sie ihre Methoden irgendwo deklarieren, wie in den Apple Docs zu Protokollen beschrieben . Normalerweise deklarieren Sie ein formelles Protokoll. Die von UIWebView.h umschriebene Deklaration würde folgendermaßen aussehen:
Dies ist analog zu einer Schnittstelle oder einer abstrakten Basisklasse, da
UIWebViewDelegate
in diesem Fall ein spezieller Typ für Ihren Delegaten erstellt wird. Delegierte Implementierer müssten dieses Protokoll übernehmen:Und dann implementieren Sie die Methoden im Protokoll. Bei Methoden, die im Protokoll als
@optional
(wie die meisten delegierten Methoden) deklariert sind , müssen Sie dies überprüfen,-respondsToSelector:
bevor Sie eine bestimmte Methode aufrufen.Benennung
Delegierungsmethoden werden normalerweise beginnend mit dem Namen der delegierenden Klasse benannt und nehmen das delegierende Objekt als ersten Parameter. Sie verwenden auch oft eine Willens-, Soll- oder Did-Form. Also
webViewDidStartLoad:
(erster Parameter ist die Webansicht) anstattloadStarted
(ohne Parameter) zum Beispiel.Geschwindigkeitsoptimierungen
Anstatt jedes Mal zu überprüfen, ob ein Delegat auf einen Selektor antwortet, wenn wir ihm eine Nachricht senden möchten, können Sie diese Informationen zwischenspeichern, wenn Delegierte festgelegt werden. Eine sehr saubere Möglichkeit, dies zu tun, besteht darin, ein Bitfeld wie folgt zu verwenden:
Dann können wir im Hauptteil überprüfen, ob unser Delegat Nachrichten verarbeitet, indem wir auf unsere
delegateRespondsTo
Struktur zugreifen-respondsToSelector:
und nicht immer wieder senden .Informelle Delegierte
Vor Protokolle gab, war es üblich , eine verwenden Kategorie auf ,
NSObject
um die Verfahren zu erklären Delegierter implementieren könnte. Zum BeispielCALayer
tut dies immer noch:Dies teilt dem Compiler mit, dass ein Objekt implementiert werden kann
displayLayer:
.Sie würden dann den gleichen
-respondsToSelector:
Ansatz wie oben beschrieben verwenden, um diese Methode aufzurufen. Delegaten implementieren diese Methode und weisen diedelegate
Eigenschaft zu, und das war's (es gibt keine Erklärung, dass Sie einem Protokoll entsprechen). Diese Methode ist in Apples Bibliotheken üblich, aber neuer Code sollte den oben beschriebenen moderneren Protokollansatz verwenden, da dieser Ansatz die Umweltverschmutzung verschmutztNSObject
(was die automatische Vervollständigung weniger nützlich macht) und es dem Compiler erschwert, Sie vor Tippfehlern und ähnlichen Fehlern zu warnen.quelle
unsigned int
Typ umwandeln,BOOL
da der Rückgabewert vondelegate respondsToSelector
vom Typ istBOOL
.Die genehmigte Antwort ist großartig, aber wenn Sie nach einer 1-minütigen Antwort suchen, versuchen Sie Folgendes:
Die Datei MyClass.h sollte folgendermaßen aussehen (Delegatenzeilen mit Kommentaren hinzufügen!)
Die Datei MyClass.m sollte so aussehen
So verwenden Sie Ihren Delegaten in einer anderen Klasse (in diesem Fall UIViewController MyVC) MyVC.h:
MyVC.m:
Implementieren Sie die Delegate-Methode
quelle
myClass
in MyVC.m instanziiert?Bei Verwendung der formalen Protokollmethode zum Erstellen der Delegatenunterstützung habe ich festgestellt, dass Sie eine ordnungsgemäße Typprüfung (allerdings Laufzeit, keine Kompilierungszeit) sicherstellen können, indem Sie Folgendes hinzufügen:
in Ihrem Delegate Accessor (setDelegate) Code. Dies hilft, Fehler zu minimieren.
quelle
Bitte! In der folgenden einfachen Schritt-für-Schritt-Anleitung erfahren Sie, wie Delegates in iOS funktioniert.
Ich habe zwei ViewController erstellt (zum Senden von Daten von einem zum anderen)
quelle
Vielleicht entspricht dies eher dem, was Sie vermissen:
Wenn Sie aus einer C ++ - Perspektive kommen, sind die Delegierten etwas gewöhnungsbedürftig - aber im Grunde funktionieren sie einfach.
So funktioniert es: Sie legen ein Objekt fest, das Sie als Delegat an NSWindow geschrieben haben, aber Ihr Objekt verfügt nur über Implementierungen (Methoden) für eine oder einige der vielen möglichen Delegatmethoden. Es passiert also etwas und Sie
NSWindow
möchten Ihr Objekt aufrufen. Es verwendet lediglich dierespondsToSelector
Methode von Objective-c, um zu bestimmen, ob Ihr Objekt diese Methode aufrufen möchte, und ruft sie dann auf. So funktioniert Objective-C - Methoden werden bei Bedarf nachgeschlagen.Es ist völlig trivial, dies mit Ihren eigenen Objekten zu tun, es ist nichts Besonderes los, Sie könnten zum Beispiel eines
NSArray
von 27 Objekten haben, alle verschiedene Arten von Objekten, nur 18 von ihnen haben die Methode-(void)setToBue;
Die anderen 9 nicht. Also, umsetToBlue
alle 18 anzurufen , die es tun müssen, so etwas:Das andere an Delegaten ist, dass sie nicht beibehalten werden, sodass Sie den Delegaten
nil
in IhrerMyClass dealloc
Methode immer festlegen müssen .quelle
Als von Apple empfohlene bewährte Methode empfiehlt es sich, dass der Delegierte (der per Definition ein Protokoll ist) dem
NSObject
Protokoll entspricht.& Um optionale Methoden in Ihrem Delegaten zu erstellen (dh Methoden, die nicht unbedingt implementiert werden müssen), können Sie die
@optional
Annotation wie folgt verwenden:Wenn Sie also Methoden verwenden, die Sie als optional angegeben haben, müssen Sie (in Ihrer Klasse) überprüfen,
respondsToSelector
ob die Ansicht (die Ihrem Delegaten entspricht) Ihre optionalen Methoden tatsächlich implementiert hat oder nicht.quelle
Ich denke, all diese Antworten sind sehr sinnvoll, wenn Sie die Delegierten verstehen. Persönlich kam ich aus dem Land von C / C ++ und davor aus prozeduralen Sprachen wie Fortran usw. Hier ist meine 2-minütige Darstellung ähnlicher Analoga im C ++ - Paradigma.
Wenn ich einem C ++ / Java-Programmierer die Delegierten erklären würde, würde ich sagen
Was sind Delegierte? Dies sind statische Zeiger auf Klassen innerhalb einer anderen Klasse. Sobald Sie einen Zeiger zugewiesen haben, können Sie Funktionen / Methoden in dieser Klasse aufrufen. Daher werden einige Funktionen Ihrer Klasse an eine andere Klasse "delegiert" (in C ++ world - Zeiger auf durch einen Klassenobjektzeiger).
Was sind Protokolle? Konzeptionell dient es einem ähnlichen Zweck wie die Header-Datei der Klasse, die Sie als Delegatenklasse zuweisen. Ein Protokoll ist eine explizite Methode, um zu definieren, welche Methoden in der Klasse implementiert werden müssen, deren Zeiger als Delegat innerhalb einer Klasse festgelegt wurde.
Wie kann ich in C ++ etwas Ähnliches tun? Wenn Sie dies in C ++ versuchen würden, würden Sie Zeiger auf Klassen (Objekte) in der Klassendefinition definieren und diese dann mit anderen Klassen verbinden, die zusätzliche Funktionen als Delegaten für Ihre Basisklasse bereitstellen. Diese Verkabelung muss jedoch im Code enthalten sein und ist ungeschickt und fehleranfällig. Ziel C geht lediglich davon aus, dass Programmierer diese Disziplin nicht am besten einhalten können, und bietet Compiler-Einschränkungen, um eine saubere Implementierung durchzusetzen.
quelle
Schnelle Version
Ein Delegat ist nur eine Klasse, die für eine andere Klasse arbeitet. Lesen Sie den folgenden Code für ein etwas albernes (aber hoffentlich aufschlussreiches) Spielplatzbeispiel, das zeigt, wie dies in Swift gemacht wird.
In der Praxis werden Delegierte häufig in den folgenden Situationen eingesetzt
Die Klassen müssen vorher nichts voneinander wissen, außer dass die Delegatenklasse dem erforderlichen Protokoll entspricht.
Ich empfehle dringend, die folgenden zwei Artikel zu lesen. Sie haben mir geholfen, die Delegierten noch besser zu verstehen als die Dokumentation .
quelle
Ok, dies ist nicht wirklich eine Antwort auf die Frage, aber wenn Sie nachschlagen, wie Sie Ihren eigenen Delegierten bilden können, könnte etwas viel Einfacheres eine bessere Antwort für Sie sein.
Ich setze meine Delegierten kaum um, weil ich sie selten brauche. Ich kann NUR EINEN Delegierten für ein Delegatenobjekt haben. Wenn Sie also möchten, dass Ihr Delegierter in eine Richtung kommuniziert / Daten weitergibt, sind Sie mit Benachrichtigungen viel besser dran.
NSNotification kann Objekte an mehr als einen Empfänger übergeben und ist sehr einfach zu verwenden. Es funktioniert so:
Die Datei MyClass.m sollte so aussehen
So verwenden Sie Ihre Benachrichtigung in anderen Klassen: Fügen Sie eine Klasse als Beobachter hinzu:
Implementieren Sie den Selektor:
Vergessen Sie nicht, Ihre Klasse als Beobachter zu entfernen, wenn
quelle
Angenommen, Sie haben eine Klasse, die Sie entwickelt haben, und möchten eine Delegate-Eigenschaft deklarieren, um sie benachrichtigen zu können, wenn ein Ereignis eintritt:
Sie deklarieren also ein Protokoll in der
MyClass
Header-Datei (oder einer separaten Header-Datei) und deklarieren die erforderlichen / optionalen Ereignishandler, die Ihr Delegat implementieren muss / sollte, und deklarieren dann eine EigenschaftMyClass
vom Typ (id< MyClassDelegate>
), was bedeutet, dass jede objektive c-Klasse konform ist Im ProtokollMyClassDelegate
werden Sie feststellen, dass die Delegate-Eigenschaft als schwach deklariert ist. Dies ist sehr wichtig, um den Aufbewahrungszyklus zu verhindern (meistens behält der Delegate dieMyClass
Wenn Sie Instanz bei. Wenn Sie den Delegaten als Retain deklariert haben, behalten sich beide gegenseitig und keine von ihnen werden jemals veröffentlicht werden).Sie werden auch feststellen, dass die Protokollmethoden die
MyClass
Instanz als Parameter an den Delegaten übergeben. Dies ist eine bewährte Methode für den Fall, dass der Delegat einige Methoden für eineMyClass
Instanz aufrufen möchte, und hilft auch, wenn sich der DelegatMyClassDelegate
für mehrereMyClass
Instanzen deklariert , z. B. wenn Sie mehrere habenUITableView's
Instanzen in IhremViewController
und erklärt sich alsUITableViewDelegate
zu allen von ihnen.und in Ihrem
MyClass
benachrichtigen Sie den Delegierten mit deklarierten Ereignissen wie folgt:Sie überprüfen zunächst, ob Ihr Delegat auf die Protokollmethode reagiert, die Sie aufrufen möchten, falls der Delegat sie nicht implementiert und die App dann abstürzt (auch wenn die Protokollmethode erforderlich ist).
quelle
Hier ist eine einfache Methode zum Erstellen von Delegaten
Protokoll in .h-Datei erstellen. Stellen Sie sicher, dass dies vor dem Protokoll mit @class gefolgt vom Namen des UIViewControllers definiert ist
< As the protocol I am going to use is UIViewController class>.
Schritt: 1: Erstellen Sie ein neues Klassenprotokoll mit dem Namen "YourViewController", das die Unterklasse der UIViewController-Klasse ist, und weisen Sie diese Klasse dem zweiten ViewController zu.
Schritt: 2: Gehen Sie zur Datei "YourViewController" und ändern Sie sie wie folgt:
Die im Protokollverhalten definierten Methoden können mit @optional und @required als Teil der Protokolldefinition gesteuert werden.
Schritt: 3: Implementierung des Delegierten
// teste, ob die Methode definiert wurde, bevor du sie aufrufst
quelle
Um Ihren eigenen Delegaten zu erstellen, müssen Sie zunächst ein Protokoll erstellen und die erforderlichen Methoden deklarieren, ohne sie zu implementieren. Implementieren Sie dieses Protokoll dann in Ihre Header-Klasse, in der Sie den Delegaten oder die Delegatmethoden implementieren möchten.
Ein Protokoll muss wie folgt deklariert werden:
Dies ist die Serviceklasse, in der eine Aufgabe ausgeführt werden sollte. Es zeigt, wie Sie einen Delegaten definieren und wie Sie den Delegaten festlegen. In der Implementierungsklasse werden nach Abschluss der Aufgabe die Methoden des Delegaten aufgerufen.
Dies ist die Hauptansichtsklasse, von der aus die Serviceklasse aufgerufen wird, indem der Delegat auf sich selbst gesetzt wird. Außerdem ist das Protokoll in der Header-Klasse implementiert.
Das war's, und durch die Implementierung von Delegate-Methoden in dieser Klasse wird die Steuerung wieder hergestellt, sobald die Operation / Aufgabe abgeschlossen ist.
quelle
Haftungsausschluss: Dies ist die
Swift
Version zum Erstellen einesdelegate
.Was sind Delegierte? … In der Softwareentwicklung gibt es allgemeine wiederverwendbare Lösungsarchitekturen, die dazu beitragen, häufig auftretende Probleme in einem bestimmten Kontext zu lösen. Diese „Vorlagen“ werden sozusagen am besten als Entwurfsmuster bezeichnet. Delegaten sind ein Entwurfsmuster, mit dem ein Objekt Nachrichten an ein anderes Objekt senden kann, wenn ein bestimmtes Ereignis eintritt. Stellen Sie sich vor, ein Objekt A ruft ein Objekt B auf, um eine Aktion auszuführen. Sobald die Aktion abgeschlossen ist, sollte Objekt A wissen, dass B die Aufgabe abgeschlossen hat, und die erforderlichen Maßnahmen ergreifen. Dies kann mit Hilfe von Delegierten erreicht werden!
Zur besseren Erklärung zeige ich Ihnen, wie Sie mit Swift in einer einfachen Anwendung einen benutzerdefinierten Delegaten erstellen, der Daten zwischen Klassen weitergibt. Laden Sie zunächst dieses Starterprojekt herunter oder klonen Sie es und führen Sie es aus!
Sie können eine App mit zwei Klassen sehen,
ViewController A
undViewController B
. B hat zwei Ansichten, die beim Tippen die Hintergrundfarbe von ändernViewController
, nichts zu kompliziert, oder? Nun wollen wir auf einfache Weise darüber nachdenken, auch die Hintergrundfarbe von Klasse A zu ändern, wenn auf die Ansichten von Klasse B getippt wird.Das Problem ist, dass diese Ansichten Teil der Klasse B sind und keine Ahnung von Klasse A haben. Daher müssen wir einen Weg finden, um zwischen diesen beiden Klassen zu kommunizieren, und hier erstrahlt die Delegation. Ich habe die Implementierung in 6 Schritte unterteilt, damit Sie diese bei Bedarf als Spickzettel verwenden können.
Schritt 1: Suchen Sie in der ClassBVC-Datei nach der Pragma-Markierung Schritt 1 und fügen Sie diese hinzu
Der erste Schritt besteht darin, ein
protocol
Protokoll zu erstellen . In diesem Fall erstellen wir das Protokoll in Klasse B. Innerhalb des Protokolls können Sie so viele Funktionen erstellen, wie Sie möchten, basierend auf den Anforderungen Ihrer Implementierung. In diesem Fall haben wir nur eine einfache Funktion, die ein optionalesUIColor
Argument akzeptiert .delegate
In diesem Fall empfiehlt es sich, Ihre Protokolle zu benennen, indem Sie das Wort am Ende des Klassennamens hinzufügenClassBVCDelegate
.Schritt 2: Suchen Sie nach der Pragma-Markierung in Schritt 2
ClassVBC
und fügen Sie diese hinzuHier erstellen wir nur eine Delegate-Eigenschaft für die Klasse. Diese Eigenschaft muss den
protocol
Typ übernehmen und sollte optional sein. Außerdem sollten Sie das schwache Schlüsselwort vor der Eigenschaft hinzufügen, um Speicherzyklen und potenzielle Speicherverluste zu vermeiden. Wenn Sie nicht wissen, was dies bedeutet, machen Sie sich vorerst keine Sorgen. Denken Sie daran, dieses Schlüsselwort hinzuzufügen.Schritt 3: Suchen Sie nach der Pragma-Markierung Schritt 3 im handleTap
method
inClassBVC
und fügen Sie diese hinzuEine Sache, die Sie wissen sollten, führen Sie die App aus und tippen Sie auf eine Ansicht. Sie werden kein neues Verhalten sehen und das ist richtig, aber ich möchte darauf hinweisen, dass die App nicht abstürzt, wenn der Delegat aufgerufen wird, und Das liegt daran, dass wir es als optionalen Wert erstellen und es deshalb nicht abstürzt, selbst wenn der Delegierte noch nicht existiert. Gehen wir jetzt zur
ClassAVC
Akte und machen es, der Delegierte.Schritt 4: Suchen Sie in der handleTap-Methode in nach der Pragma-Markierung Schritt 4
ClassAVC
und fügen Sie diese wie neben Ihren Klassentyp ein.Jetzt hat ClassAVC die
ClassBVCDelegate
Protokoll übernommen hat, können Sie sehen, dass Ihr Compiler Ihnen einen Fehler mit der Meldung "Typ" ClassAVC entspricht nicht dem Protokoll "ClassBVCDelegate" anzeigt. Dies bedeutet nur, dass Sie die Methoden des Protokolls noch nicht verwendet haben. Stellen Sie sich das vor Wenn Klasse A das Protokoll annimmt, ist das wie das Unterzeichnen eines Vertrags mit Klasse B und dieser Vertrag besagt: "Jede Klasse, die mich adoptiert, MUSS meine Funktionen nutzen!"Kurzer Hinweis: Wenn Sie aus einem
Objective-C
Hintergrund stammen, denken Sie wahrscheinlich, dass Sie diesen Fehler auch beenden können, indem Sie diese Methode optional machen. Zu meiner und wahrscheinlich Ihrer Überraschung wird dieSwift
Sprache jedoch nicht optionalprotocols
unterstützt. Wenn Sie dies möchten, können Sie sie erstellen eine Erweiterung für Ihreprotocol
oder verwenden Sie das Schlüsselwort @objc in Ihrerprotocol
Implementierung.Persönlich, wenn ich ein Protokoll mit verschiedenen optionalen Methoden erstellen muss, würde ich es vorziehen, es in verschiedene zu unterteilen
protocols
. Auf diese Weise folge ich dem Konzept, meinen Objekten eine einzige Verantwortung zu übertragen, aber es kann je nach spezifischer Implementierung variieren.hier ist ein guter Artikel über optionale Methoden.
Schritt 5: Suchen Sie nach der Pragma-Markierung Schritt 5 in der Methode zur Vorbereitung auf den Übergang und fügen Sie diese hinzu
Hier erstellen wir nur eine Instanz von
ClassBVC
und weisen ihren Delegierten dem Selbst zu, aber was ist das Selbst hier? Nun, Selbst ist das,ClassAVC
was delegiert wurde!Schritt 6: Suchen Sie abschließend nach dem Pragma in Schritt 6
ClassAVC
und verwenden Sie die Funktionen vonprotocol
, beginnen Sie mit der Eingabe von func changeBackgroundColor, und Sie werden sehen, dass es automatisch für Sie vervollständigt wird. Sie können eine beliebige Implementierung hinzufügen. In diesem Beispiel ändern wir nur die Hintergrundfarbe und fügen diese hinzu.Führen Sie jetzt die App aus!
Delegates
sind überall und Sie verwenden sie wahrscheinlich ohne Vorankündigung. Wenn Sie einetableview
in der Vergangenheit verwendete Delegation erstellen , lösen viele Klassen vonUIKIT
Arbeiten um sie herum und viele andereframeworks
diese Hauptprobleme.Herzlichen Glückwunsch, Sie implementieren gerade einen benutzerdefinierten Delegaten. Ich weiß, dass Sie wahrscheinlich denken, so viel Ärger nur dafür? Nun, Delegation ist ein sehr wichtiges Entwurfsmuster, um zu verstehen, ob Sie ein werden möchten
iOS
Entwickler werden , und denken Sie immer daran, dass sie eine Eins-zu-Eins-Beziehung zwischen Objekten haben.Das Original-Tutorial finden Sie hier
quelle
Die Antwort wird tatsächlich beantwortet, aber ich möchte Ihnen einen "Spickzettel" zum Erstellen eines Delegaten geben:
quelle
ViewController.h
ViewController.m
MainViewController.m
Methode:
quelle
Aus meiner Sicht erstellen Sie eine separate Klasse für diese Delegatmethode, und Sie können sie verwenden, wo Sie möchten.
in meiner benutzerdefinierten DropDownClass.h
danach in.m Datei Array mit Objekten erstellen,
Hier sind alle für die benutzerdefinierte Delegatenklasse festgelegt. Danach können Sie diese Delegatenmethode verwenden, wo Sie möchten. Zum Beispiel ...
in meinem anderen viewcontroller danach importieren
Erstellen Sie eine Aktion zum Aufrufen dieser Delegatenmethode
danach Aufruf delegate Methode wie folgt
quelle
Delegieren: - Erstellen
Senden Sie und weisen Sie den Delegierten zu, um anzuzeigen, dass Sie Daten senden
quelle
// 5. Implementieren Sie die Methode in der Klasse .m - (void) didRemoveCellWithTag: (NSInteger) tag {NSLog @ ("Tag% d", tag);
}}
quelle
Beginnen wir mit einem Beispiel: Wenn wir ein Produkt online kaufen, durchläuft es einen Prozess wie Versand / Lieferung, der von verschiedenen Teams abgewickelt wird. Wenn der Versand abgeschlossen ist, sollte das Versandteam das Lieferteam benachrichtigen und es sollte eine Eins-zu-Eins-Kommunikation sein, um diese Informationen zu senden Dies wäre ein Overhead für andere Personen / Anbieter, die diese Informationen möglicherweise nur an erforderliche Personen weitergeben möchten.
Wenn wir also in Bezug auf unsere App denken, kann eine Veranstaltung eine Online-Bestellung sein und verschiedene Teams können wie mehrere Ansichten sein.
Hier ist der Code, der ShippingView als Versandteam und DeliveryView als Lieferteam betrachtet:
quelle