为什么Apple的闭包声明缺少参数标签

时间:2017-01-06 20:41:48

标签: ios swift swift3 closures

在我阅读UIKit时,大部分时间我都会看到闭包(作为函数参数),其缺少参数标签,如下所示:func fooClosure(fooClosure: (Bool) -> Swift.Void)

在某些情况下,我可以猜出它代表什么,在其他情况下,我不能。

实施例

看看UIActivityViewController的一个闭包(作为类型别名):

public typealias UIActivityViewControllerCompletionWithItemsHandler = (UIActivityType?, Bool, [Any]?, Error?) -> Swift.Void

第三类型代表什么?我必须查看代码的 Objective-C 版本才能知道这些是returnedItems

为什么没有这样实现:(请注意activityItems标签)

public typealias UIActivityViewControllerCompletionWithItemsHandler = (UIActivityType?, Bool, _ activityItems: [Any]?, Error?) -> Swift.Void

编辑: - 这只是一个临时状态(因为Swift尚未完全集成在这些框架中)? 没有参数标签,代码可读性较差。

3 个答案:

答案 0 :(得分:2)

问题是这是由机器生成的函数签名类型,并且机器没有按照您的意愿执行操作。请考虑以下Objective-C声明:

typedef void (^MyCoolType)(NSString* __nullable name);

Swift生成的界面是:

public typealias MyCoolType = (String?) -> Swift.Void

如你所见,name被剥夺了;它无处可见。

在Swift中,没有什么能阻止定义带有内部标签的函数签名类型。这是合法的:

public typealias MyCoolType = (_ name:String?) -> Void

但这并不是从Objective-C生成生成的接口的方式。

答案 1 :(得分:1)

从Swift 3开始,关键字不再是关闭类型的一部分,因此它们不会出现(并且不会出现)类型的任何位置预期,例如在type aliasfunc声明中。

有关详细信息,请参阅this post中的答案。

答案 2 :(得分:1)

闭锁设计用途广泛。您没有参数名称,因为您创建的用于传入的功能可能与其他人权限的功能大不相同。

请记住,参数名称属于功能

为了说明,当我创建一个函数时,我会这样做:

func getUser(for name: String) -> User {
    // Stuff here...
}

我添加标签,以便我自己和其他人知道如何正确使用该功能。

闭包参数不是函数,你传入函数。一个人写的功能可以创建一个芝士汉堡,而另一个人可以写一个旋转视图180º并且转换到新的视图控制器。

通过UIView上的Apples文档示例,有一个名为completion的结束闭包。顾名思义,动画完成时会触发此函数。现在文档解释了Bool值告诉你动画是否完成,这是函数本身不明显的。

如果您不确定参数的用途(例如上面的例子),请查看文档。

希望这能回答你的问题。