我试图在所有符合协议的UIViewControllers中添加点按功能MyProtocol。
以下是我的做法:
import UIKit
protocol MyProtocol: class{
var foo: String? {get set}
func bar()
}
extension MyProtocol where Self: UIViewController {
func bar() {
print(foo)
}
}
class TestViewController: UIViewController, MyProtocol{
var foo: String?
override func viewDidLoad() {
super.viewDidLoad()
foo = "testing"
let tapGesture = UITapGestureRecognizer(target: self, action: "bar")
}
Run Code Online (Sandbox Code Playgroud)
点击屏幕时,结果如下:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: unrecognized selector sent to instance
我了解该错误,但不知道如何解决。谁能建议如何做到这一点?
问题在于,Objective-C不了解协议扩展。因此,您不能使用协议扩展将方法注入到类中,而Objective-C的消息传递机制可以看到该方法。您需要bar在视图控制器类本身中声明。
(我意识到这正是您要避免这样做的方法,但是我无能为力。)
一种解决方法可能是这样的:
override func viewDidLoad() {
super.viewDidLoad()
foo = "testing"
let tapGesture = UITapGestureRecognizer(target: self, action: "baz")
self.view.addGestureRecognizer(tapGesture)
}
func baz() {
self.bar()
}
Run Code Online (Sandbox Code Playgroud)
现在,我们使用Objective-C的消息传递机制进行调用baz,然后使用Swift的消息传递机制进行调用bar,这当然是有效的。我意识到它不像您所想的那样干净,但是至少现在实现bar可以在协议扩展中使用。
(当然,另一种解决方案是做在协议扩展存在之前我们所做的事情:使所有视图控制器都从某个包含的通用自定义UIViewController子类继承bar。)
| 归档时间: |
|
| 查看次数: |
1388 次 |
| 最近记录: |