0

is anyone able to tell me why this does not work in Swift 3? I have a protocol which conforms to AnyObject like this:

protocol EventListenerProtocol: AnyObject {
    func doSomething()
}

then I have an emitter protocol with default implementation like this:

protocol EventEmitterProtocol {
    associatedtype ListenerType

    var listeners: [ListenerType] { get set }

    func addEventListener(_ listener: ListenerType)
    func removeEventListener(_ listener: ListenerType)
}

extension EventEmitterProtocol where ListenerType: AnyObject {

  ... funcs implemented ...

}

removeEventListener requires ListenerType to be AnyObject to be able to use identity operator.

After all that, I'm trying to use this in my class:

class myClass: EventEmitterProtocol {

    var listeners: [EventListenerProtocol] = []

}

and it says my class does not conform to EventEmitterProtocol. When I change EventListenerProtocol to AnyObject as the array type, it does compile. EventListenerProtocol conforms to AnyObject, so why the error pops up? I'd be really grateful for any help :)

Hamish
  • 78,605
  • 19
  • 187
  • 280
Suryu
  • 25
  • 1
  • 9
  • Possible duplicate of [Protocol doesn't conform to itself?](http://stackoverflow.com/questions/33112559/protocol-doesnt-conform-to-itself) – Hamish Feb 21 '17 at 14:30
  • I think this is a different case, because my error message says that myClass does not conform to EventEmitterProtocol. – Suryu Feb 21 '17 at 14:34
  • It's the same problem, as `EventListenerProtocol` is not a type that conforms to `AnyObject` – thus you don't get the `extension EventEmitterProtocol where ListenerType: AnyObject` with the default implementations of your methods, meaning your class doesn't conform to `EventEmitterProtocol`, as it doesn't have an implementation for those method requirements. – Hamish Feb 21 '17 at 14:36
  • I still have no idea how to solve my problem tho. Sorry, this is still a bit complicated for me, as I'm rather new to Swift. I want to be able to add and remove listeners to myClass using addEventListener and removeEventListener funcs, but this would work from different places, so listener must be a protocol, I also wanted to move the default implementation to the Emitter protocol. Do I have to move it back to the main class, or is there some way to get through it? I read the answers on the link you gave, but it didn't help me much to solve the problem. – Suryu Feb 21 '17 at 14:43
  • You'll likely have to build [a type eraser](http://robnapier.net/erasure) (as the linked Q&A suggests) in order to wrap a `EventListenerProtocol` conforming instance in a concrete type, and then have an array of that concrete type for your `listeners`. – Hamish Feb 21 '17 at 16:48

0 Answers0