2016-08-07 12 views
1

Betrachten Sie den folgenden Code. Alles wird vom Buch erledigt, nur dass dem Delegaten eine Instanz einer anderen Klasse als self zugewiesen wird. Doch dieser Code schlägt fehl - der Delegat wird nie aufgerufen. Warum das?Nicht-Selbst-Delegat heißt nicht

class My: UITextField { 
    ... 
    init(...) { 
    delegate = MyDelegate() 
    } 
} 

public class MyDelegate: NSObject, UITextFieldDelegate { 
    public func textFieldDidBeginEditing(_ textField: UITextField) { 
    print("MyDelegate was called") 
    } 
} 
+0

Diese Zeile: 'öffentliche Überschreibung func didLoad() {' Ursachen 'Fehler: Methode überschreibt keine Methode aus ihrer Oberklasse'. – OOPer

Antwort

1

Wenn Ihr Delegat Eigenschaft definiert ist ein weak var verwenden, die MyDelegate Instanz nicht beibehalten werden. Ohne eine starke Referenz wird es in Kürze freigegeben und existiert nicht mehr, um Anrufe zu empfangen.

Ihr Beispielcode Streuner aus dem typischen Muster Delegierten:

class MyViewController: UITextFieldDelegate { 

    ... 

    func viewDidLoad() { 
     myTextField.delegate = self 
    } 

    func textFieldDidBeginEditing(_ textField: UITextField) { 
     print("textFieldDidBeginEditing") 
    } 
} 
+1

Es wäre hilfreich, diese Antwort mit der Lösung des Problems zu erweitern (im Allgemeinen wird eine starke Eigenschaft für "My" benötigt, die sich auf "MyDelegate()" befindet). Dies ist ein sehr häufiger Fehler, BTW. Ich habe es letzte Woche gemacht; brauchte zehn Minuten, um herauszufinden, warum es nicht funktionierte. –

+1

Danke, das ist in der Tat das Problem. Innerhalb von 'UITextField' ist der Delegat definiert als' schwacher öffentlicher var-Delegierter: UITextFieldDelegate? ', Der, wie @dene beobachtet hat, keine zugewiesenen Dinge behält, es sei denn, sie werden zusätzlich von jemand anderem referenziert. – j4zzcat

+0

Dies ist nicht hilfreich; Das OP wollte nicht selbst als Delegat, sie wollten eine neue Klasse, um die Delegiertenanrufe zu behandeln. – robertfiorentino

0

didLoad ist keine Funktion von UITextField so wird Ihre Stellvertretung nicht wirklich festgelegt, und das ist, warum es nicht genannt wird. Wenn Sie Ihre Klasse My programmgesteuert erstellen, können Sie den Delegaten nach dem Erstellen der Instanz festlegen.

let myTextField = My() 
mytextField.delegate = MyDelegate() 

Wenn Sie die Delegierten jedes Mal wenn Sie Klasse festlegen möchten erstellt wird, müssen Sie die init-Funktionen von UITextField außer Kraft zu setzen und den Delegaten in Ihrer init-Funktionen zu erstellen.

class MyTF : UITextField 
{ 
    override init(frame: CGRect) 
    { 
    super.init(frame: frame) 
    delegate = MyDelegate() 
    } 

    required init?(coder aDecoder: NSCoder) 
    { 
    super.init(coder: aDecoder) 
    delegate = MyDelegate() 
    }  
} 
0

Sie können dies erreichen, indem eine zu erstellen:

Delegation and the Cocoa Frameworks

The delegating object is typically a framework object, and the delegate is typically a custom controller object.

View-Controller des Textfelds selbst allgemein als Textfeld des Delegaten zuweisen würde Geben Sie zuerst mit "let" einen starken Verweis auf Ihre Delegatklasse ein, und legen Sie dann den Delegaten fest. Andernfalls, weil die Delegat-Referenz schwach ist, wird es eine Referenzzahl von Null und keine Ausgabe haben, so dass Sie keinen Delegaten haben.