swift - 如何在 Swift / Xcode 12.3 中重用代码块进行闭包
问题描述
在我的 iOS 应用程序中,我正在运行一个 HKStatisticsCollectionQuery,它有一个
query.initialResultsHandler = { query, results, error in [...] }
和一个
query.statisticsUpdateHandler = { query, hkStats, results, error in [...] }
两个闭包完全相同。
有没有办法只编写一次这些闭包的代码并引用它两次?通常我会重构/提取一个函数并调用它,但在这里我有一个
DispatchQueue.main.async { ... }
在处理程序内部,所以我不确定它会起作用......正如你可能从我的问题中推断的那样,我不确定我是否正在关闭和 dispatchQueue 好吧......
解决方案
闭包和函数是可以互换的。任何需要传递闭包的地方,都可以传递一个函数。
因此,您可以为这两种情况编写一个函数并传递该函数名称而不是闭包。
也就是说,您的两个示例显示了不同的参数,这与您“两个闭包完全相同”的说法相矛盾。如果它们采用不同的参数,它们怎么可能相同?
编辑:
考虑以下函数:
func foo(value: String, completion: (String)->Void) {
completion(value)
}
正如你所料,我们可以使用闭包调用 foo:
foo(value: "firstCall", completion: { value in
print("in completion handler, value = '\(value)'")
})
那会输出
在完成处理程序中,值 = 'firstCall'
我们还可以定义一个或多个签名匹配完成处理程序的函数:
func completionFunction(value: String) {
print("In \(#function), value = '\(value)'")
}
func completionFunctionTwo(value: String) {
print("In \(#function), value = '\(value)'")
}
然后像这样调用那些:
foo(value: "secondCall", completion: completionFunction)
foo(value: "thirdCall", completion: completionFunctionTwo)
请注意我们只是将函数名称作为完成处理程序传递。这相当于传递一个内联闭包。
这些调用将输出:
在 completionFunction(value:), value = 'secondCall'
在 completionFunctionTwo(value:), value = 'thirdCall'
最后,您可以创建一个包含闭包的变量,并将其作为完成处理程序传递:
let aCompletionClosure: (String) -> Void = { value in
print("In completion closure, value = '\(value)'")
}
foo(value: "forthCall", completion: aCompletionClosure)
输出:
在完成关闭中,value = 'forthCall'
推荐阅读
- arrays - Swift:如何从数组中的结构访问特定数据?
- java - 如何使用 VelocityTemplate 转义撇号
- dependency-injection - 对 gmock 对象应用 ON_CALL 无效
- mysql - Django 模型列行为
- python - 使用 tinytag 和 PIL 将字节转换为图像
- java - 如何将 charCount 集成到 for 循环中
- google-cloud-firestore - Firestore 集合写入限制(由顺序更新的索引字段强加)是否受集合组查询的影响?
- python-3.x - 带有 Base64 pfx 证书的 Python 请求
- javascript - 我不断收到“未定义”作为错误,函数不返回任何内容
- python - 如何确定 self.attribute 是否在 __init__() 中定义?