我在这个例子中模拟了我的情况:
protocol MyProtocol {
func doSomething()
}
extension MyProtocol {
func doSomething() {
print("Do something")
}
}
class MyViewController: UIViewController, MyProtocol {
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(doSomething), for: .touchUpInside)
}
}
我原以为MyViewController
已经实施了doSomething()
功能,因为它是在MyProtocol
扩展名中实现的。不幸的是我收到了这个错误:
错误:' #selector'的参数指实例方法 ' doSomething的()'没有暴露于Objective-C
我可以修复或解决此问题吗?
答案 0 :(得分:0)
您的协议与Objective-C不兼容。您需要使用@objc
对其进行注释,否则您将无法使用选择器,因为这些方法不会使用Objective-C调度。
修改强>
所以我应该在之前在的操场上尝试过它。。
您无法在Swift中向协议扩展添加@objc
函数。你必须把它放在课堂上。或者你可以扩展UIViewController来实现MyProtocol
e.g。
@objc protocol MyProtocol
{
@objc func doSomething();
}
extension UIViewController: MyProtocol
{
@objc func doSomething() { /* implementation */ }
}
答案 1 :(得分:0)
我遇到了同样的问题并用包装对象解决了它。
protocol MyProtocol: class {
func doSomething()
}
extension MyProtocol {
func doSomething() {
print("Do something")
}
}
final class ObjCMyProtocolWrap: NSObject, MyProtocol {
// MARK: - init
override init() {
fatalError("Not supported!")
}
init(_ origin: MyProtocol) {
self.origin = origin
}
// MARK: - protocol: Executable
func doSomething() {
origin.doSomething()
}
// MARK: - private
private let origin: MyProtocol
}
现在你可以像这样使用它:
let action: MyProtocol = OriginalObject()
let objcAction: MyProtocol = ObjCMyProtocolWrap(action)
button.addTarget(objcAction, action: #selector(ObjCMyProtocolWrap.doSomething), for: .touchUpInside)
但请注意:您必须存储对包装对象的引用(本例中为objcAction)! UIButton只有弱引用!