3

While playing around in playground with protocol extension I came to strange error. More precisely I declared a protocol and used it as type in the following manner :

protocol InvokeProtocol{

    func invokeA()

    func invokeB()
}

class Controller{

    var invoker : InvokeProtocol?

    func methodA(){

        invoker?.invokeA()
    }

    func methodB(){

        invoker?.invokeB()
    }
}

What I did next was creating a subclass of Controller and tried to extend the InvokeProtocol for that particular type

extension InvokeProtocol where Self: SpecificController{

    func invokeC(){

    }

}

class SpecificController : Controller {

    override func methodA() {
        super.methodA()
    }

    override func methodB() {
        super.methodB()
    }

    func methodC(){
        invoker?.invokeC()   
    }
}

But this give me the following compile time error while I try to call invokeC on SpecificController

@opened("70A8B09C-65E3-11E5-9A8E-6C40088AF546") InvokeProtocol' is not a subtype of 'SpecificController'

I just jumped to Swift 2.0 and this is my first time I see errors starting with @opened. What does this mean? Is this a known bug waiting to be fixed? If so do you guys have any workaround about this?

Zell B.
  • 10,266
  • 3
  • 40
  • 49
  • If you remove the `where Self: SpecificController` it will work. The error message makes sense to me. You can't extend it that way because your `SpecificController` doesn't implement the `InvokeProtocol` protocol. – Adam Sep 28 '15 at 13:35
  • @Adam Then why will I need protocol extension at all? I want to be able to call `invokeC` method only from `SpecificController` and no from other classes that adopt 'InvokeProtocol'. – Zell B. Sep 28 '15 at 13:39

2 Answers2

2

To reply to your comment. It is achievable. You just haven't implemented the protocol in the first place. The following will work:

protocol InvokeProtocol {

    func invokeA()

    func invokeB()
}

class Controller : InvokeProtocol {

    func invokeA(){
    }

    func invokeB() {
    }
}

extension InvokeProtocol where Self: SpecificController{

    func invokeC() {

    }

}

class SpecificController : Controller {

    override func invokeA() {
        super.invokeA()
    }

    override func invokeB() {
        super.invokeB()
    }

    func invokeC() {
    }
}
Adam
  • 26,549
  • 8
  • 62
  • 79
  • I still want to use protocol as a type. And what about @opened error? – Zell B. Sep 28 '15 at 13:58
  • What do you mean by "to use protocol as a type"? And for `@opened` error, perhaps you should ask another question. – Adam Sep 28 '15 at 14:07
  • With protocol as a type I mean using protocol object directly e.x `var invoker : InvokeProtocol?` . As for `@opened` I see this as a good thread since this issue is producing that error – Zell B. Sep 28 '15 at 14:21
  • `var invoker : InvokeProtocol?` is totally possible. That was not a problem. The problem is that you wanted to extend a protocol only for specific caller. This is not possible in Swift, that's not possible with any language I know. – Adam Sep 28 '15 at 14:26
0

I guess the where Self: SpecificController, the Self means var invoke: InvokeProtocol?

if invoke conform the protocol and invoke is SpecificController, that invoke can call the method named invokeC()

Klein Mioke
  • 1,261
  • 2
  • 14
  • 23