swift - 为什么在 Swift 中通过 Selector 调用时函数的默认参数不被尊重?
问题描述
通过 Selector 调用的方法不遵守默认参数值。
例子
如果我有一个连接按钮以通过选择器调用函数:
func setupButton() {
self.button.addTarget(self, action: #selector(printValue), for: .touchUpInside)
}
@objc func printValue(value:Int = 7)
{
if value == 7 {
print("received default")
} else {
print("default unused")
}
}
通过代码调用此方法时会打印“收到的默认值”,但是当我按下按钮并通过选择器调用该方法时,会打印“默认未使用”,因为未将 7 设置为值。
为什么会这样?
解决方案
调用函数时,Swift 编译器会插入默认参数。
所以这是编译时的事情。
当通过选择器手动调用函数时,您使用的是 Objective-C 运行时,它不知道您的默认参数。
这是运行时的事情。
此外,Objective-C 中不存在默认参数。
您可以将 Swift 默认参数视为编译时的便利。
但是一旦你运行你的代码,它们基本上就消失了。
编辑
如果您正在寻找解决方法,我可以建议使用两个不同的函数,而不使用默认参数:
@objc func printValue()
{
printValue(value: 7)
}
@objc func printValue(value:Int)
{}
这样,您可以通过 Objective-C 运行时不带参数地调用它。请注意,使用 时#selector
,您需要强制转换以解决歧义:
self.button?.addTarget(self, action: #selector((printValue as () -> Void)), for: .touchUpInside)
推荐阅读
- if-statement - Crystal Reports 的“if 语句”帮助
- ffmpeg - ffmpeg 在我的这行代码中添加循环
- c - 接受调用阻塞线程终止
- ruby-on-rails - 显示页面 has_many has_one 关联上的未初始化常量 ruby
- python - 在 Django 中处理多种类型的用户
- javascript - 如何在不创建新 obj 的情况下连接到数组对象?
- perl - 如何在不考虑查询参数排序的情况下测试 URI 相等性
- python - 如何永久删除密集层中节点之间的连接
- wordpress - NGINX + 乘客 w/ Rails + WordPress 永久链接
- c++ - 输入 trait 以接收 T::value_type 如果存在,否则为 T