gpt4 book ai didi

ios - Swift:使用协议(protocol)扩展导致 "unrecognized selector sent to instance"

转载 作者:可可西里 更新时间:2023-11-01 00:23:05 24 4
gpt4 key购买 nike

我正在尝试向所有符合 MyProtocol 协议(protocol)的 UIViewController 添加点击功能。

下面是我的做法:

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")
}

点击屏幕时会出现以下结果:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:无法识别的选择器发送到实例

我明白这个错误,但不知道如何修复它。谁能建议如何做到这一点?

最佳答案

问题是 Objective-C 对协议(protocol)扩展一无所知。因此,您不能使用协议(protocol)扩展以 Objective-C 的消息传递机制可以看到的方式将方法注入(inject)到类中。您需要在 View Controller 类自身中声明bar

(我知道这正是您试图避免做的事情,但我无能为力。)

一种解决方法可能是这样的:

override func viewDidLoad() {
super.viewDidLoad()

foo = "testing"
let tapGesture = UITapGestureRecognizer(target: self, action: "baz")
self.view.addGestureRecognizer(tapGesture)
}

func baz() {
self.bar()
}

我们现在使用 Objective-C 的消息传递机制来调用 baz,然后使用 Swift 的消息传递机制来调用 bar,当然可以。我意识到它并不像您想象的那么干净,但至少现在 bar 的实现可以存在于协议(protocol)扩展中。

(当然,另一个解决方案是做我们在协议(protocol)扩展存在之前所做的事情:让你所有的 View Controller 继承自一些包含 bar 的通用自定义 UIViewController 子类。)

关于ios - Swift:使用协议(protocol)扩展导致 "unrecognized selector sent to instance",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35809253/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com