Wie erstelle ich einen Delegaten mit eigenem Protokoll

Selbst in den meisten einfachen Tutorial können Sie erfüllen die Verwendung von Protokollen. Es wird sicherlich für viele gerade in Ihrer View-Controller ein Protokoll verwenden, verteilen, neben dem Interface-Definition, eine Aussage wie:

1
2
3
UIViewController <UIWebViewDelegate> { @ Schnittstelle MyViewController: UIViewController {<UIWebViewDelegate>
...
}


Die Protokolle (in dem obigen Beispiel <UIWebViewDelegate> ) eine bestimmte Art von Ziel-C Verhaltensweisen einer Klasse in eine andere erben. In dem oben gezeigten Beispiel wahrscheinlich unsere View-Controller verwaltet eine Komponente UIWebView . In dem Wunsch, an Veranstaltungen des letzteren enthält das Protokoll reagieren UIWebViewDelegate .
, come ad esempio: So das Protokoll implementiert UIWebViewDelegate in unserem View-Controller, können wir in der Datei setzen m Implementierungsmethoden (Nachrichten), die von der Komponente aufgerufen wird. UIWebView , wie zB:

1
2
3
void ) webViewDidFinishLoad : ( UIWebView * ) webView { - (Void) webViewDidFinishLoad: (UIWebView *) webview {
/ / Laden der Seite abgeschlossen
}

In anderen Worten, unsere View-Controller teilt die Schnittstelle <UIWebViewDelegate> , dass "einige" caratteristice erbt.

Schreiben Sie Ihren eigenen Protokoll

. Stellen Sie sich vor, wir haben zwei Klassen: ClasseA und ClasseB . che, a sua volta, genera un messaggio quando accade un determinato evento. Die Klasse ClasseA instanziiert im ClasseB , die wiederum erzeugt eine Nachricht, wenn ein bestimmtes Ereignis passiert. per rispondere e intercettare gli “eventi” rilasciati da ClasseB . Dann wollen einen Delegaten für das schreiben ClasseB die durch verwendet werden kann ClasseA zu reagieren und fangen die "Events" ausgestellt ClasseB .
: Das erste, was zu tun ist, fügen Sie das Protokoll in definierten ClasseB zusammen mit einem Objekt (in der Standard-Apple-) delegate :

1
2
3
4
5
6
7
8
9
10
11
@ Protokoll ClasseBDelegate <NSObject>
@ Optional
void ) mioEvento : ( id ) sender; - (Void) mioEvento: (id) sender;
@ End

NSObject { @ Schnittstelle ClassB: NSObject {
/ / Andere Definitionen
id <ClasseBDelegate> delegiert;
}

assign ) id <ClasseBDelegate> delegate; @ Property (zuordnen) id <ClasseBDelegate> delegiert;

. Wie üblich in der Datei M ClasseB In den Warenkorb

1
@ Synthesize Delegierter;

Bei der Implementierung der Klasse Datei ClasseB können Sie das "Feuer" unserer Veranstaltung in dieser Art und Weise:

1
2
3
self.delegate != NULL && [ self.delegate respondsToSelector : @selector ( mioEvento : ) ] ) { if (self.delegate = NULL && [self.delegate respondsToSelector: @ selector (mioEvento :)]) {
self ] ; [MioEvento Delegierter: self];
}

: [self.delegate respondsToSelector:@selector(mioEvento:)] . Zuerst müssen wir überprüfen, ob Sie einen Delegaten gesetzt: self.delegate != NULL und die dieser Delegat gibt, oder kann auf die Nachricht reagieren mioEvento : [self.delegate respondsToSelector:@selector(mioEvento:)] . ) che è il puntatore all'istanza della classe ClassB . Wenn beide Bedingungen überprüft werden dann aufrufen mioEvento ; in diesem Beispiel, wird dieses Ereignis auch ein Parameter ( id ), die der Zeiger auf die Instanz der Klasse ist ClassB .
: Die Klasse ClassA nicht tun müssen, ist den Delegaten Methode implementieren und geben Sie den mioEvento :

1
2
3
4
5
6
7
# Import "ClasseB.h"

NSObject <ClasseBDelegate> { @ Schnittstelle ClassA: NSObject {<ClasseBDelegate>
...
}

void ) mioEvento : ( id ) sender; - (Void) mioEvento: (id) sender;

Bei der Umsetzung Datei erstellen, wenn wir ClassB wir verwenden:

1
2
[ ClasseB alloc ] ; ClassB ClassB * = [ClassB alloc];
self ] ; [ClassB setDelegate: self];

Dann legen:

1
2
3
void ) mioEvento : ( id ) sender { - (Void) mioEvento: (id) sender {
"mioEvento" ) ; NSLog (@ "mioEvento");
}

12 Kommentare zu: ""

  1. 6. Januar 2011 Luigi:

    Hallo,
    Artikel Komplimente!
    Ich wollte meine Zweifel über die Verwendung zu klären ...

    Der Delegat wird normalerweise aufgerufen, wenn ein Ereignis eintritt ... in diesem Fall, nachdem wir die "Delegierten" Methode "mioEvento" erstellt wurden, müssen von Hand aufgerufen werden?
    Ich verstand nicht, diesen Schritt
    Vielen Dank.

  2. 9. Januar 2011 Giovan Battista Fazioli :

    @ Luigi: ja, die Klasse, die das Protokoll von uns erstellt unterstützt wird auch die Aufgabe haben, den Delegaten-Methode aufrufen. Wie oben in unserer Klasse all'accadere Ereignis angezeigt Ausführen von Code ähnlich:

    1
    2
    3
    self.delegate != NULL && [ self.delegate respondsToSelector : @selector ( mioEvento : ) ] ) { if (self.delegate = NULL && [self.delegate respondsToSelector: @ selector (mioEvento :)]) {
    self ] ; [MioEvento Delegierter: self];
    }

    Das heißt, wenn Sie einen Delegaten und diesen Delegaten unterstützen die angeforderte Methode gesetzt, so wird das Verfahren ausgeführt.
    Im Prinzip pesonali Klassen, von mittlerer Komplexität, müssen - es ist der Fall - supportatre ein Protokoll, um sie über Zustände und Ereignisse der Klasse selbst zu informieren.
    Wenn Sie schreiben, alle anderen Fragen.

  3. 9. Januar 2011 Luigi:

    Danke ...
    Ich habe eine andere Frage ... ergibt sich aus der Tatsache, dass ich nicht hatte eine Hand in Code und vielleicht schießen Unsinn : D

    Erstelle meine Protokoll, und lassen Sie uns davon ausgehen, dass dieses Ereignis all'accadere Ich erinnere mich an eine bestimmte Methode Protokoll wie Sie gerichtet haben.
    Die Durchführung des Verfahrens wird im Laufe tun. M meiner Protokoll

    Wenn ich eine Methode, die Teil meiner Klasse delegiert (dh derjenige, der die Delegierten verwendet) wie verfahren wird nennen können?
    Ich habe meine Idee, aber ich werde nicht schreiben bagianate

  4. 9. Januar 2011 Giovan Battista Fazioli :

    @ Luigi: Wenn ich Ihre Frage verstehen, normalerweise sind Sie mit zwei Fällen konfrontiert. Normalerweise haben Sie eine View-Controller, dass neben das Objekt, das einen bestimmten Protokoll unterstützt instanziieren macht es auch als Delegierter. In diesem Fall, wenn Sie die Durchführung des Verfahrens zu schreiben und hat direkten Zugriff auf das Objekt-Instanz, die das Protokoll zur Verfügung stellt. Dies kann wie folgt skizziert werden:

    1
    2
    3
    UIViewController <myClassADelegate> { @ Schnittstelle MyViewController: UIViewController {<myClassADelegate>
    myClassA * Objecta;
    }

    e, come detto sopra, se funzngerà anche da delegato per la myClassA nell'implementazione del metodo avrà accesso alla variabile objectA : myViewController instanzierà das Objekt des Typs myClassA und, wie oben erwähnt, wenn auch für die funzngerà delegieren myClassA in der Durchführung des Verfahrens haben Zugriff auf die Variable objectA :

    1
    2
    3
    4
    void ) mioEvento { - (Void) {mioEvento
    / / Do something
    ; [Objecta myMethod];
    }

    In laternativa gibt es Fälle, in denen der Delegat ist ein Objekt einer anderen Klasse, wie folgt aus:

    1
    2
    3
    4
    5
    6
    / / Wir sind in einer View-Controller
    ...
    myClassA alloc ] init ] ; Objecta = [[myClassA alloc] init];
    [ [ myClassB alloc ] init ] ; myClassB ObjectB * = [[myClassB alloc] init];
    objectA.delegate = ObjectB;
    ...

    . In diesem Fall wird ein View-Controller instanziiert die Klasse myClassA deutete dies als Delegierter myClassB . che, ovviamente, non conosce a priopri il puntatore alla myClassA . Die Veranstaltung wird von generierten myClassA durch verwaltet werden myClassB natürlich nicht weiß, um den Zeiger an priopri myClassA .
    qualcuno deve passargliela; questo qualcuno è il view controller che conosce entrambe. In diesem Fall, wenn die Instanz von myClassB muss mit der Instanz interagieren myClassA jemand muss es passieren, und dieser jemand ist die View-Controller, die sowohl kennt. Also der obige Code sollte von der Art sein:

    1
    2
    3
    4
    5
    6
    7
    / / Wir sind in einer View-Controller
    ...
    myClassA alloc ] init ] ; Objecta = [[myClassA alloc] init];
    [ [ myClassB alloc ] init ] ; myClassB ObjectB * = [[myClassB alloc] init];
    objectA ] ; // informa B di A [ObjectB setObjectAPointer: Objecta]; / / B informiert von A
    objectA.delegate = ObjectB;
    ...

    Wenn ich verstehe die Frage nicht ...

  5. 10. Januar 2011 Luigi:

    im ersten Fall ...
    Ich rufe die Methode myMethod die offensichtlich haben ihre eigene Implementierung.

    Naja ... bei der Umsetzung berücksichtigen wir, um eine Aktion, die einen Aufruf einer Methode oder die Verwendung einer Variablen in meinem MyViewController erfordert durchführen

    Wie kann ich?
    Ich hoffe, ich erklärt!

  6. 10. März 2011 Objective-C: Mitteilungen und Delegierten | Undolog.com :

    [...] Elegant, klar und einfach zu verwenden, um mit diesen Situationen umzugehen. Wir haben bereits über in Wie ein Delegierter mit eigenem Protokoll erstellen gesprochen. Objective-C können Sie ein Kommunikationsprotokoll, durch welche eine oder mehrere Klassen [...] definieren

  7. 2. Februar 2012 Marco:

    Hallo, herzlichen Glückwunsch von meiner Seite für den Artikel .. Ich habe ein Anliegen wir exportieren ..
    Ich bin in dem Fall, in dem sie in einem Tab-Controller, hat jeder eine eigene Klasse viewController

    tab1: PrimoController
    tab2: OptionController

    was ich tun möchte, ist in der Lage, Anhalten und startare einen Timer, der auf PrimoController dall'OptionController ist, dieser Timer habe ich auch startare können und Stoppen von der ersten Steuerung mit 2 Methoden

    1
    2
    3
    4
    5
    6
    void ) startTimer { - (Void) {startTimer
    / / NSTimer bla bla bla
    }
    void ) stopTimer { - (Void) {stopTimer
    / / Timer invalidate bla bla bla
    }

    Ich habe es getan:
    in OptionViewController.h I erstellt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @ Protokoll OptionViewControllerDelegate
    @ Erforderlich
    void ) timerActionRestart; - (Void) timerActionRestart;
    @ End

    UITableController @ Schnittstelle DptionViewController: UITableController

    weak, nonatomic ) id timerHandlerDelegate; @ Property (schwach, nonatomic) id timerHandlerDelegate;

    @ End

    in OptionViewController.m I:

    1
    2
    3
    4
    5
    6
    7
    8
    void ) metodoGestoreTimer - (Void) metodoGestoreTimer
    {
    timerHandlerDelegate != nil ) { if (timerHandlerDelegate! = nil) {
    "timerActionRestar" ) ; NSLog (@ "timerActionRestar");
    ; [Self.timerHandlerDelegate timerActionRestart];
    }

    }

    Und so ist alles ok .. Hand in der ersten Klasse ist die Situation seguetne:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    / ** PrimaClasse.h ** /

    # Import "OptionViewController.h"

    NSObject @ Schnittstelle DptionViewController: NSObject

    / ** PrimaClasse.m ** /
    void ) timerActionRestart - (Void) timerActionRestart
    {
    / / Stop-Timer
    / / Start-Timer
    ) ; NSLog ("timer Neustart");
    }

    Ich verstehe, dass ich den Delegierten eingestellt haben, aber ist 2 Klassen haben bereits initialisiert wurde, weiß ich nicht, wie das zu tun!
    Haben Sie eine Idee?

    Gerade jetzt bekannt, dass metodoGestoreTimer genannt wird, aber nicht alles, was sich seit der IF die Kontrolle nicht ..

    Vielen Dank und herzlichen Glückwunsch noch einmal für den Blog! : D

  8. 2. Februar 2012 Marco:

    vergessen .. del delegato l'ho messo in OptionViewController der @syntetize Ich legte den Delegierten : D

  9. 2. Februar 2012 Marco:

    Leider Spam .. Ich habe bemerkt, dass es ein Fehler ..
    Hier ist die Korrektur

    1
    2
    3
    4
    / ** PrimaClasse.h ** /
    # Import "OptionViewController.h"

    NSObject @ Schnittstelle PrimaClasse: NSObject
  10. 2. Februar 2012 Giovan Battista Fazioli :

    @ Markus: Ich glaube, ich würde eine richtige Ansatz empfehlen. Wenn Sie die Unterklasse folgte die Registerkarte Steuerung, hält dieser die Liste aller View-Controller. Die Frage muss in diesen Bedingungen gelesen werden: die View-Controller auf einen anderen Controller Option bittet um eine Operation auszuführen (aktivieren oder deaktivieren Sie einen Timer). Die View-Controller-Option ist ein "Sohn", wie die anderen, die Registerkarte Steuerung. Es ist daher richtig, dass die Nachricht von der View-Controller-Option auf die Registerkarte Steuerung, die wiederum die Meldung an die zuständigen Behörden smisterà geht. Die Registerkarte View-Controller kennt alle seine View-Controller, so dass es eine Nachricht an jemanden zu schicken. Die View-Controller kennt seine Optionen Registerkarte Steuerung per Definition.
    Wenn ich Zeit habe, werde ich versuchen, ein Beispiel-Code geben, aber ich glaube, ich habe euch gegeben alle erforderlichen Angaben zur Durchführung individuell. Lassen Sie mich wissen, wenn ich etwas verpasst auf dem Weg ...

  11. 2. Februar 2012 Marco:

    Vielen Dank, ich habe angezündet : D
    Ich löste es, indem Sie

    1
    2
    3
    4
    5
    6
    7
    / / OptionViewController.m
    void ) viewDidLoad { - (Void) {viewDidLoad
    ....
    / / Delegierter des Septum starten Sie den Timer
    viewControllers = self.tabBarController.viewControllers; NSArray * = ViewControllers self.tabBarController.viewControllers;
    viewControllers objectAtIndex : 0 ] ; self.timerHandlerDelegate = [ViewControllers objectAtIndex: 0];
    }

    Jetzt funktioniert alles!
    ich danke Ihnen sehr!

Hinterlasse einen Kommentar

TAG XHTML PERMITS: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> Code-Eingabe:
 <pre></pre> // blocco generico <code></code> // blocco generico [cc_actionscript][/cc_actionscript] // Actionscript [cc_actionscript3][/cc_actionscript3] // Actionscript 3 [cc_css][/cc_css] // CSS Style Sheet [cc_html][/cc_html] // HTML [cc_js][/cc_js] // Javascript [cc_objc][/cc_objc] // Objective-C [cc_php][/cc_objc] // PHP [cc_sql][/cc_sql] // SQL