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