2016-02-13 2 views
8

Ich versuche, Delegationsaufgaben in den Griff zu bekommen und streiche es auf eine grundlegende Implementierung. Ich bin dazu gekommen, aber die Delegiertenfunktion wird nie aufgerufen. Könnte jemand etwas Licht werfen?Wie mache ich eine grundlegende Implementierung von Delegation in Swift?

protocol MyDelegate{ 
    func delegatedFunction (a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate? 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    func delegatedFunction (a:String){ 
     print(a) 
    } 
} 
+0

Sie benötigen Verbinden Sie die Variable Delegate mit der DelegateClass, bevor Sie mit dem Aufruf fortfahren. In diesem Fall rufen Sie eine Funktion über einen Nullwert auf, der ein Laufzeitfehler ist! – kandelvijaya

+0

Die Delegierung ähnelt der interface-basierten Komposition von Objekten. Dies ist eine Möglichkeit, Objekte und Verantwortlichkeiten zu entkoppeln. Sie können vielleicht besser zu schätzen wissen, wenn Sie die ersten 3 Kapitel von Head First mit Design Patterns lesen. – kandelvijaya

Antwort

1

Eine Instanz DelegateClass selbst einstellen muss als Delegierter einer Instanz DelegatorClass

So würden Sie so etwas wie haben:

class DelegateClass: MyDelegate { 
    func delegatedFunction (a:String){ 
     print(a) 
    } 

    func testFunction() { 
     var delegator=DelegatorClass() 
     delegator.delegate=self 
     delegator.callDelegate() 
    } 
} 
4

Code verwenden, dies ist der Weg Delegat richtig verwenden. wenn Sie callDelegate() nennen, wird die Referenz des DelegateClass nehmen und delegatedFunction()

protocol MyDelegate{ 
    func delegatedFunction (a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate? 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    let my_class= DelegatorClass() 
    my_class.delegate = self 

    func delegatedFunction (a:String){ 
     print(a) 
    } 
} 

Blick auf Apfel Protokolle Dokumentationen für weitere Informationen auszuführen. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

+0

Das ergibt folgende Fehler: let class = DelegatorClass() // Schlüsselwort 'class' kann nicht als Bezeichner verwendet werden class.delegate = self // Erwartete Deklaration –

+1

ups, mein Schlechter, ich habe es nicht getestet, ich werde es bearbeiten die Post. – UlyssesR

+0

Großartig, danke. Diese Zeile: "my_class.delegate = self" gibt immer noch einen Erwarteten Deklarationsfehler. Irgendeine Idee warum? Sollte diese Linie innerhalb der Funktion sein? –

7
let myDelegatorObj = DelegatorClass() 
myDelegatorObj.delegate = DelegateClass() 
myDelegatorObj.callDelegate() 

Punkt ist, bevor Sie rufen callDelegate() müssen Sie die delegate zuweisen. Um zu überprüfen, ob Ihre Delegation funktioniert, können Sie die DelegatorClass mit dem Delegaten initialisieren.

class DelegatorClass { 
    var delegate: MyDelegate? = DelegateClass() 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 
+2

Das sieht nach dem Weg aus. Ich würde jedoch angeben, dass das erste Beispiel und das zweite Beispiel unterschiedliche Ansätze zum Aktivieren der Delegierung sind. Das erste Beispiel ist am vielseitigsten, da es erlaubt, eine andere Delegiertenklasse zu verwenden, ohne es in der Delegatorklasse –

+0

@MarcoPappalardo fest zu codieren. 2. Beispiel ist nur für Test. –

3

Getestet und auf einer Probe Spielplatz arbeiten.

import UIKit 

protocol MyDelegate { 
    func delegatedFunction(a: String) 
} 

class DelegatorClass { 

    var delegate: MyDelegate? 

    func callDelegate() { 
     delegate?.delegatedFunction("Hello World!") 
    } 
} 

class DelegateClass: MyDelegate { 

    let my_class = DelegatorClass() 

    init() { 
     my_class.delegate = self 
    } 

    // MyDelegate Protocol implementation 
    func delegatedFunction(a: String) { 
     print(a) 
    } 

} 

Um es zu testen, fügen Sie die folgenden Zeilen unten hinzu.

let c = DelegateClass() 
c.my_class.callDelegate() 

erklären zu,

Wenn Sie die Instanz von DelegateClass c und es initialisiert wird, die init Methode erstellen ausgeführt. Die DelegatorClass-Instanz my_class Mitglied delegate enthält jetzt einen Verweis auf self, die die DelegateClass ist.

Wenn nun die callDelegate() Methode ausgeführt wird, da die optionale Variable delegate jetzt einen Verweis auf die DelegateClass Instanz enthält, ruft sie grundsätzlich für die Durchführung der delegatedFunction(a: String) Methode. Und deshalb wird die Zeichenkette a gedruckt.

Beachten Sie auch, dass der Grund, warum ich my_class.delegate = self innerhalb init() setzen musste, ist, weil Sie nur Instanzeigenschaftsdeklarationen außerhalb von Methoden in einer Klasse haben können. Alle Funktionen sollten in Methoden gehen.

Ich hoffe, dass die Erklärung klar war! :)

-1
protocol Delegate{ 

    func callMe() 
    func textMe() 
} 

@objc protocol DelegateWithOptional: class{ 

    optional func callMe() 
    func textMe() 
} 

class SomeClass{ 

    var delegate: Delegate? 

    func call(){ 
     delegate?.callMe() 
    } 

    func text(){ 
     delegate?.textMe() 
    } 

} 

class SomeClass2{ 

    var delegateWithOptional: DelegateWithOptional? 

    func call(){ 
     delegateWithOptional?.callMe() 
    } 

    func text(){ 
     delegateWithOptional?.textMe() 
    } 
} 

class ClassConfirmingToProtocol: SuperClass, Delegate{ 

    var someClass = SomeClass() 
    override func viewDidLoad(){ 
     someclass.delegate = self 
    } 

    //must implement this method 
    func textMe(){ 
     //do something 
    } 

    //must implement this method 
    func callMe(){ 
     //do something 
    } 

} 

class ClassConfirmingToProtocolWithOptional: SuperClass, DelegateWithOptional{ 

    var someClass2 = SomeClass2() 
    override func viewDidLoad(){ 
     someclass2.delegate = self 
    } 

    //must implement this method 
    func textMe(){ 
     //do something 
    } 

    //optional to implement this method, i.e. even without this method, its not gonna throw any error 
    func callMe(){ 
     //do something 
    } 

} 
4
protocol MyDelegate{ 
    func delegatedFunction (a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate? 
    func callDelegate() { 
     delegate?.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    func delegatedFunction (a:String){ 
     print(a) 
    } 
} 
let delegator = DelegatorClass() 
delegator.callDelegate() // print nothing, because delegate is nil by default 

// set your delegate !!!!!!! 
delegator.delegate = DelegateClass() 
delegator.callDelegate() // print "hello" 

Es ist nichts falsch mit Ihrem Ansatz, verwenden Sie es genau die richtige Art und Weise.Der Punkt ist die Delegatvariable für eine Instanz des Typs T, die dem Protokoll MyDelegate entspricht. In Ihrem Fall ist dies die DelegateClass-Instanz. Im Allgemeinen könnte T fast alles sein, das dem MyDelegate-Protokoll entspricht.

struct S:MyDelegate { 
    func delegatedFunction(a: String) { 
     print("Hello from struct conforming to MyDelegate protocol") 
    } 
} 

delegator.delegate = S() 
delegator.callDelegate() // print "Hello from struct conforming to MyDelegate protocol" 

delegator.delegate = nil 
delegator.callDelegate() // print nothing again :-) 
2

Sie haben es fast, Sie einfach die class DelegateClass zum class DelegatorClassdelegate Eigenschaft, mit einigen anderen zwickt zuweisen vergessen.

Grundsätzlich sagen Sie die class DelegateClass, um die protocol MyDelegate zu entsprechen, was bedeutet, dass es delegatedFunction(a:String) implementieren muss. Auf class DelegatorClass wird die delegate Eigenschaft erwartet ein Objekt mit einer Art von protocol MyDelegate zugeordnet werden, so dass es die Protokollfunktion gegen sie aufrufen können, damit von der Bedeutung zuweisen self zum delegate Eigenschaft in DelegateClass

protocol MyDelegate{ 
    func delegatedFunction(a:String) 
} 

class DelegatorClass { 
    var delegate: MyDelegate! = nil 
    func callDelegate() { 
     delegate.delegatedFunction("hello") 
    } 
} 

class DelegateClass: MyDelegate { 
    var delegator:DelegatorClass = DelegatorClass() 

    init() { 
     delegator.delegate = self 
     delegator.callDelegate() 
    } 
    func delegatedFunction (a:String){ 
     print(a) 
    } 
}