I'm trying to mark a variable of a generic type as weak:
class X<T> {
weak var t: T?
}
If I don't put in any constraints for T
I get the error weak cannot be applied to non-class type 'T'
.
If I would only use use this with NSObject derived classes this would work:
class X<T: NSObject> {
weak var t: T?
}
But I also want to be able to use pure Swift classes.
For protocols it is possible to require that the implementor is of class type by using the class
keyword:
protocol ClassType: class {
}
With the ClassType
protocol I can now mark the variable as weak:
class X<T: ClassType> {
weak var t: T?
}
But I cannot add the class
keyword directly to the generic parameter:
class X<T: class> { // Compile error
weak var t: T?
}
I can make the protocol solution work for all NSObject derived classes with an extension:
extension NSObject: ClassType {
}
But for pure Swift classes there is no common superclass that I could add this extension to. Is there a way to make this work without adding the ClassType
protocol to each class I want to use the X
class with? E.g. some special qualifier for the generic parameter like class X<T:ThisIsAClass>
?
Generics in Swift allows you to write generic and reusable code, avoiding duplication. A generic type or function creates constraints for the current scope, requiring input values to conform to these requirements.
Protocol 'Equatable' can only be used as a generic constraint because it has Self or associated type requirements.
Multiple interface constraints can be specified. The constraining interface can also be generic.
You want AnyObject
, which the Swift docs describe as:
The protocol to which all classes implicitly conform.
class X<T: AnyObject> {
weak var t: T?
}
class C { }
let x = X<C>() // works fine
x.t = C()
// error: type 'Int' does not conform to protocol ‘AnyObject’
// (because Int is a struct)
let y = X<Int>()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With