the following code gives me a compile error
'WeakReference' requires that 'ServiceDelegate' be a class type
protocol ServiceDelegate: AnyObject { func doIt() } class SomeClass() { // compile error occurs in this line private var observers = [WeakReference<ServiceDelegate>]() } WeakReference code:
final class WeakReference<T: AnyObject> { private(set) weak var value: T? init(value: T?) { self.value = value } } How can I fix this error? Delegate should be declared correctly as per this site.
What I have tried so far:
AnyObject to class does not solve the problem.You can't have a WeakReference<ServiceDelegate>. ServiceDelegate itself is not an AnyObject, it just requires that anything that conforms to it be an AnyObject.
You would need to make SomeClass generic and use the generic type as the type for the WeakReference:
class SomeClass<T: ServiceDelegate> { private var observers = [WeakReference<T>]() } If the generic on SomeClass is too constricting and you want to be able to have instances of multiple unrelated classes as observers then I would do it by abandoning the generic parameter on WeakReference:
final class WeakServiceDelegate { private(set) weak var value: ServiceDelegate? init(value: ServiceDelegate?) { self.value = value } } class SomeClass { private var observers = [WeakServiceDelegate]() } Alternatively you could make WeakReference conditionally conform to ServiceDelegate:
extension WeakReference: ServiceDelegate where T: ServiceDelegate { func doIt() { value?.doIt() } } And then use an array of ServiceDelegate in SomeClass:
class SomeClass { private var observers = [ServiceDelegate]() func addObserver<T: ServiceDelegate>(_ observer: T) { observers.append(WeakReference(value: observer)) } }
As you see, ServiceDelegate is a protocol, not a class type. Even if all types which can conform to ServiceDelegate are class types, ServiceDelegate itself is not a class type. It is the fact of the pure Swift protocols currently.
Try @obc, Objective-C protocols are a bit different:
@objc protocol ServiceDelegate { func doIt() } You may want to exclude Objective-C something and to make some pure Swift classes conform to ServiceDelegate, but I cannot find other ways around.
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