Mam klasę, która musi wywołać delegata, gdy zmieni się jedna z jego właściwości. Oto uproszczona klasa i protokół dla delegata:Delegat Swift dla ogólnej klasy
protocol MyClassDelegate: class {
func valueChanged(myClass: MyClass)
}
class MyClass {
weak var delegate: MyClassDelegate?
var currentValue: Int {
didSet {
if let actualDelegate = delegate {
actualDelegate.valueChanged(self)
}
}
}
init(initialValue: Int) {
currentValue = initialValue
}
}
To wszystko działa dobrze. Ale chcę, aby ta klasa była ogólna. Tak, próbowałem to:
protocol MyClassDelegate: class {
func valueChanged(genericClass: MyClass)
}
class MyClass<T> {
weak var delegate: MyClassDelegate?
var currentValue: T {
didSet {
if let actualDelegate = delegate {
actualDelegate.valueChanged(self)
}
}
}
init(initialValue: T) {
currentValue = initialValue
}
}
To powoduje dwa błędy kompilatora. Po pierwsze, linia deklarująca valueChanged
w protokole daje: Reference to generic type 'MyClass' requires arguments in <...>
. Po drugie, wywołanie valueChanged
w obserwatorze didSet
powoduje: 'MyClassDelegate' does not have a member named 'valueChanged'
.
myślałem użyciu typealias
rozwiązałoby problem:
protocol MyClassDelegate: class {
typealias MyClassValueType
func valueChanged(genericClass: MyClass<MyClassValueType>)
}
class MyClass<T> {
weak var delegate: MyClassDelegate?
var currentValue: T {
didSet {
if let actualDelegate = delegate {
actualDelegate.valueChanged(self)
}
}
}
init(initialValue: T) {
currentValue = initialValue
}
}
I wydaje się być na dobrej drodze, ale nadal mam dwa błędy kompilatora. Drugi błąd z powyższego pozostaje, jak również nowy w linii deklarującej właściwość delegate
z MyClass
: Protocol 'MyClassDelegate' can only be used as a generic constraint because it has Self or associated type requirements
.
Czy jest jakiś sposób, aby to osiągnąć?
To jest dokładnie to, co potrzebne ... dzięki. – GarlicFries
Dla tego, co jest warte, 'valueChanged' jest wywoływane w powyższym kodzie w obserwatorze' didSet' na 'currentValue'. – GarlicFries
Świetna odpowiedź. Udało mi się stworzyć delegata na moją generyczną klasę. Mam kolejne pytanie. Jak mogę rozróżnić, który elementowy delegat obiektu wywołuje funkcję delegowania ogólnego?thing1 or thing2? Proszę zobaczyć ten punkt. https://gist.github.com/zakkhoyt/0b2543bb5a5995b41e73bef83391c378 – VaporwareWolf