type A requires that type B be a class type swift 4
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.
The problem is that WeakReference<ServiceDelegate>
is wrong at line
private var observers = [WeakReference<ServiceDelegate>]()
You have to use a concrete class instead of protocol inside <>
You have two possible solutions:
- Create a concrete class and use it:
class ServiceClass: ServiceDelegate { //... } private var observers = [WeakReference<ServiceClass>]()
Or use a protocol. I mean this:
final class WeakReference<T: AnyObject> { private(set) weak var value: T? init(value: T?) { self.value = value } } protocol SomeContainer: AnyObject { } extension WeakReference: SomeContainer { }
and use this way:
private var observers = [SomeContainer]()
Note
Using this way:
class SomeClass<T: ServiceDelegate> {
private var observers = [WeakReference<T>]()
}
You just move the problem to another part of the code.
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))
}
}