在Swift函数签名中,参数后的!表示什么?更具体地说,这是指参数在传入之前需要展开,还是在传入时(自动)展开.下面是一个例子:

func annotationButtonTUI(sender: UIButton!) { }

在这种情况下,该函数是UIButton的目标,因此无论!发生什么,都会自动发生.

我的 idea 是,这意味着你可以期待一个sender个展开的对象,所以你不需要try 展开它.

推荐答案

这并不是完全重复——除了在其他地方的使用之外,隐式打开in function signatures个选项还有一些微妙之处.

在从ObjC导入的API中可以看到隐式展开的选项,因为这是一个对象的最接近的Swift近似值,该对象预计会在那里,但可能为零.这是对导入API的一种折衷——您可以像在ObjC中一样直接处理这些变量,并且可以使用Swift可选语法测试它们是否为零.(WWDC14的Advanced Interoperability talk篇文章中有更多关于苹果的理由.)这种模式也适用于Interface Builder插入的IBAction个声明,因为这些方法实际上也是从ObjC代码中调用的.

正如您所怀疑的那样,当从ObjC桥接时,Swift将可能的nil封装在可选值中,但函数实现声明中的!会将该值展开,以便您可以直接使用它.(风险自负.)

自Swift 1.2(2015年 spring 的Xcode 6.2)以来,ObjC API可以用nonnullnullable进行注释,在这种情况下,这些API的Swift接口使用非可选类型或完全可选类型.(自从Swift 2.0/Xcode 7.0以来,几乎所有苹果的API都经过审计,使用了可空性注释,因此他们的Swift签名不再使用太多注释.)

关于这一点,不太为人所知的是,当您实现自己的Swift函数时,您可以自由地更改参数的可选性,这些函数会被ObjC调用.如果希望编译器强制执行action方法中的sender永远不能为nil,则可以从参数类型中go 掉!.如果希望编译器确保始终测试参数,请将!改为?.

Swift相关问答推荐

运行异步任务串行运行

如何防止自动状态恢复,如果应用程序被启动打开特定的文档?

阻塞(受CPU限制的)任务的异步功能?

SWIFT闭包使用的是陈旧的值,即使它是S@转义

可以将属性名称传递给 Swift 中的函数吗?

当模式以编程方式关闭时在父视图控制器中触发操作

解码 JSON 时 Swift Struct Decoder 初始化程序错误

macOS 的窗口框架中使用的真实类型和真实类型是什么?

快速更改tableView中的数据

如何为 Swift UI 视图定义 struct ?

获取具有关联类型的协议的self

如何删除标签和步进按钮之间的间距是 SwiftUI Stepper?

临时添加到视图层次 struct 后,Weak view引用不会被释放

单元测试和私有变量

在 Swift 中返回实例类型

将if let与逻辑或运算符一起使用

从 NSData 对象在 Swift 中创建一个数组

如何从 Swift 中的字符串生成条形码?

将强制向下转换视为可选将永远不会产生零

如何在 Swift 中将 NSURL 转换为字符串