2016-03-21 3 views
4

Lassen Sie uns sagen, ich habe sehr einfache Klasse:für Klasse

class Box<T> { 
    var boxedObject:T 

    init(object: T) { 
    self.boxedObject = object 
    } 
} 

Was möchte ich jetzt zu erreichen, ist Delegaten hinzuzufügen, die mir diesen Wert in Feld informieren hat sich geändert:

protocol BoxDelegate<T>: class { 
    func valueInBoxChanged(box: Box<T>) -> Void 
} 

class Box<T> { 
    var boxedObject: T { 
     didSet { 
      self.delegate?.valueInBoxChanged(self) 
     } 
    } 
    weak var delegate: BoxDelegate<T>? 

    init(object: T) { 
     self.boxedObject = object 
    } 
} 

Dieser Code funktioniert natürlich nicht, da wir keine generischen Delegaten haben. Ich kann Delegat zu einer Struktur mit Schließung machen, aber es ist eine hässliche Lösung. Wie sollte ich solche Dinge in Swift machen?

+0

In diesem speziellen Fall, wo der Delegat nur eine Methode implementiert, würde ich vorschlagen, einfach die generische Typ-Deklaration auf die Methode selbst zu verschieben. Natürlich wäre das unelegant, wenn das Protokoll mehrere Methoden deklariert, aber in diesem einfachen Fall ist es ziemlich dasselbe –

Antwort

0

Aufgrund des typenbeschränkten Protokolls mit Swift können Sie möglicherweise nicht das tun, was Sie zuvor versucht haben. Was Sie tun könnten, ist eine Schließung zu erstellen, wenn der Delegat gesetzt ist und die Schließung später aufzurufen.

Hier ist, was Ihr Fall einfacher zu einem gewissen Grad machen würde,

protocol BoxDelegate: class { 
    associatedtype T 
    func valueInBoxChanged(box: Box<T>) -> Void 
} 

class Box<T> { 

    var notifyClosure: (Void -> Void)? 

    var boxedObject: T { 
     didSet { 
      self.notifyClosure?() 
     } 
    } 

    func setBoxDelegate<M where M:BoxDelegate, M.T == T>(delegate: M) { 
     notifyClosure = { 
      delegate.valueInBoxChanged(self) 
     } 
    } 

    init(object: T) { 
     self.boxedObject = object 
    } 
} 

So müssen Sie nicht zusätzliche Struktur mit einem Verschluss daran zu arbeiten haben, hinzufügen müssen. Stattdessen würden Sie keine Eigenschaft für BoxDelegate erstellen, sondern eine Methode erstellen, um diese Eigenschaft festzulegen und darauf basierend ein Schließobjekt zu erstellen.