Unrecognized Selector 怎么可能出现在 Xcode9/Swift4 中?
How is UnrecognizedSelector even possible in Xcode9/Swift4?
代码完成在 #selector(
中填写方法的名称,然后在运行时继续崩溃,并出现无法识别选择器的错误,(IllegalArgumentException)。
将选择器语法重做为不再只是字符串的意义何在?
这里是选择器的创建:
headerAddButton.addTarget(section, action: #selector(addActivityToSpecificDay(sender:)), for: .touchDown)
部分(此处引用)是表视图的 header 部分(忘记提及,此代码在 Xcode 9 之前有效):
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
这里是处理程序的方法签名:
@objc func addActivityToSpecificDay (sender :UIButton)
当然在同一个源文件中。但是请阅读问题:如果代码完成可以找到它,我到底是怎么导致运行时崩溃的?
您正在像这样添加目标:
headerAddButton.addTarget(section, action: #selector(addActivityToSpecificDay(sender:)), for: .touchDown)
因为你的 #selector
没有用 class 限定 addActivityToSpecificDay
,它显然与当前 class 中同名的某些方法相匹配,而不是无论 class section
是什么。
有两种选择:
将 addActivityToSpecificDay
移动到任何 class section
中(为了说明的目的,假设它是 SectionClass
)并引用 class 在你的 #selector
:
headerAddButton.addTarget(section, action: #selector(SectionClass.addActivityToSpecificDay(sender:)), for: .touchDown)
或者在当前class中保留addActivityToSpecificDay
,但将addTarget
的目标改为self
:
headerAddButton.addTarget(self, action: #selector(addActivityToSpecificDay(sender:)), for: .touchDown)
你问:
What was the point of redoing the selector syntax as no longer just strings??
它验证了选择器的函数存在且格式正确(这是一件非常好的事情),但它显然无法验证选择器的 class 恰好与某些 class 相同其他参数(本例中的 target
)。编译器无法可靠地知道 addTarget
方法如何使用选择器,也无法知道两个参数之间存在某种特殊关系。这留给了开发者。 #selector
语法有帮助,但它不是灵丹妙药。
代码完成在 #selector(
中填写方法的名称,然后在运行时继续崩溃,并出现无法识别选择器的错误,(IllegalArgumentException)。
将选择器语法重做为不再只是字符串的意义何在?
这里是选择器的创建:
headerAddButton.addTarget(section, action: #selector(addActivityToSpecificDay(sender:)), for: .touchDown)
部分(此处引用)是表视图的 header 部分(忘记提及,此代码在 Xcode 9 之前有效):
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
这里是处理程序的方法签名:
@objc func addActivityToSpecificDay (sender :UIButton)
当然在同一个源文件中。但是请阅读问题:如果代码完成可以找到它,我到底是怎么导致运行时崩溃的?
您正在像这样添加目标:
headerAddButton.addTarget(section, action: #selector(addActivityToSpecificDay(sender:)), for: .touchDown)
因为你的 #selector
没有用 class 限定 addActivityToSpecificDay
,它显然与当前 class 中同名的某些方法相匹配,而不是无论 class section
是什么。
有两种选择:
将
addActivityToSpecificDay
移动到任何 classsection
中(为了说明的目的,假设它是SectionClass
)并引用 class 在你的#selector
:headerAddButton.addTarget(section, action: #selector(SectionClass.addActivityToSpecificDay(sender:)), for: .touchDown)
或者在当前class中保留
addActivityToSpecificDay
,但将addTarget
的目标改为self
:headerAddButton.addTarget(self, action: #selector(addActivityToSpecificDay(sender:)), for: .touchDown)
你问:
What was the point of redoing the selector syntax as no longer just strings??
它验证了选择器的函数存在且格式正确(这是一件非常好的事情),但它显然无法验证选择器的 class 恰好与某些 class 相同其他参数(本例中的 target
)。编译器无法可靠地知道 addTarget
方法如何使用选择器,也无法知道两个参数之间存在某种特殊关系。这留给了开发者。 #selector
语法有帮助,但它不是灵丹妙药。