为什么在某些情况下添加Swift协议不需要所有正常需要的方法?

问题描述 投票:0回答:1

例如,这些都是有效的,并且不需要(所有)协议存根就可以编译。

public class ViewController: UIViewController, SFSpeechRecognizerDelegate {

}


class BLEController: CBCentralManager, CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {

    }
}

编辑:解决了! 在不继承UIViewController或CBCentralManager的情况下创建一个类,仍然符合委托协议,但不符合NSObjectProtocol。 这似乎只是我试图以一种非预期的方式使用框架。

swift swift-protocols
1个回答
0
投票

为什么我的代码编译时没有满足所有的协议要求?

你在这里看到的是 可选协议要求. 它们在这里是因为Swift代码需要与Objective-C交互,而Objective-C有它们。

所有方法除了 centralManagerDidUpdateState 宣布在 CBCentralManagerDelegate 是可选的。从此:

唯一需要的方法是 centralManagerDidUpdateState(_:);当中央管理器的状态更新时,中央管理器会调用这个,从而表明中央管理器的可用性。

而且 SFSpeechRecognizerDelegate,只包含一个可选方法。从此:

使用这个协议的可选方法来跟踪这些变化,并提供一个适当的响应。


那为什么去掉超类后代码就不能编译了呢?

这是因为你问题中的这两个协议也都继承自 NSObjectProtocol因此,他们实际上也有额外的要求。NSObjectProtocol. UIViewControllerCBCentralManager 都继承了 NSObject,所以它们满足 NSObjectProtocol 要求,但你的Swift类没有超级类。

带有可选需求的协议不必继承于 NSObjectProtocol 虽然。只是在框架中大部分都是这样的。比如你可以这样做。

@objc protocol Foo {
    @objc optional func foo()
}

class FooClass : Foo {
    // compiles fine!
}

0
投票

它不需要协议存根就能编译,因为所有的需求都是可选的。在声明中检查 SFSpeechRecognizerDelegate 它只需要一个叫做 availabilityDidChange 你可以看到,它的 optional 从函数开头给出的关键字中提取。

在第二种情况下, class 你所创建的不继承于 NSObject 但第一种确实如此,因为它是一个子类的 UIViewController 而它又是 NSObject.

© www.soinside.com 2019 - 2024. All rights reserved.