访问协议 returns 范围错误中的可选方法

Accessing optional method in protocol returns scope error

我已经用尽了关于这个主题的所有 SO 线程,但没有得到任何关于这个错误的信息。 代码设置:

@objc protocol MyProtocol: NSObjectProtocl{
    @objc optional func myFunction()
}

class MyClass: NSObject, MyProtocol {
    func doSomething() {
        myFunction?() //Error: cannot find myFunction in scope.
        self.myFunction() //Error: Value of type 'MyClass' has no member 'myFunction'
    }
}

我尝试过的事情:

if self.responds(to: #selector(MyProtocol.myFunction)){
    self.myFunction?() //Error: Value of type 'MyClass' has no member 'myFunction'
}
extension MyProtocol  {
    @objc func myFunction(){ //Error: @objc can only be used with members of classes, @objc protocols, and concrete extensions of classes.
    }
}

使用 MyClass 的其他 Objective-C 实现需要 myFunction,因此我需要使用 @objc 公开 myFunction。

如果我想使用它,是否必须在 MyClass 中实现 myFunction。这个问题是在将文件从 Obj-C 转换为 Swift 时出现的,其中 Obj-C 允许调用可选方法而无需检查它们的实现。

class MyClass: NSObject, MyProtocol { ... }

这表示 MyClass 实现了 MyProtocol,它允许但不需要 myFunction。编译器可以清楚地看到 MyClass 没有实现 myFunction,所以 self.myFunction() 不是问题。 可能是一回事,但显然不是一回事。协议对此不起作用。

您可以通过说“我不是说 MyClass;我是说 MyProtocol”来“解决”这个问题:

func doSomething() {
    (self as MyProtocol).myFunction?()
}

但这在我看来有点愚蠢。 self 没有实现 myFunction,这在编译时是已知的。

如果重点是通过子类化来实现,正确的方法是在超类中将其实现为空:

class MyClass: NSObject, MyProtocol {
    func myFunction() {}

    func doSomething() {
        myFunction()
    }
}

这正好等同于“什么都不做”,同时允许在子类中进行覆盖。