从不调用函数的完成处理程序有什么影响?
What are the effects of never calling a function's completion handler?
如果您从不调用完成处理程序会怎样?有没有什么副作用?我假设可能存在内存泄漏,但我找不到任何文档。
func completeMe(completionHandler: @escaping (String?) -> Void) {
return
}
由于参数命名为 completionHandler
,您的调用者将假定它会被执行,无论如何。
因此,为了回答您的问题,不会有任何固有的副作用,但它可以被视为一种不好的做法。
从根本上说,"completion handler" 没有什么特别之处。这只是一个功能。
如果你有函数:
func f() {
print("Hello, world")
}
你不调用它,会发生什么?好吧,什么都没有发生。
现在,这意味着什么?正如 rmaddy 提到的,如果函数 有 完成,调用者肯定期望调用该完成。 充其量 一个函数完成并且调用者不关心完成是否曾经 运行.*
是不寻常的
想象一下,该函数由一个视图控制器调用,该视图控制器在调用之前启动一个 activity 指示器,然后在完成时停止该指示器。如果从未调用完成,则指标永远不会停止旋转。
基本上就是这样。 如果未调用完成,则其代码不会 运行。其效果完全取决于完成期间和周围代码中发生的事情。
好的,你提到了内存...很多时候,完成处理程序将是一个匿名函数。在那种情况下,是一个创建的对象。但它与任何其他对象都遵循相同的内存管理规则。没有泄漏 只是因为 它没有被调用。如果 completeMe
看起来像这样:
func completeMe(_ completionHandler: (String) -> Void) {
completionHandler("Hello, world")
}
你这样称呼它:
completeMe({ self.detailLabel.text = [=12=] })
然后为匿名函数创建的对象不会在 completeMe
returns 之后存活。如果你存储匿名函数:
func completeMe(_ completionHandler: @escaping (String) -> Void) {
self.handler = completionHandler
// Do other things
}
然后与任何其他对象一样发生同样的事情:匿名函数一直存在,直到 属性 被设置为另一个值 (同时假设没有其他对象有参考一下).
如果你传入一个命名函数,
func takeAString(_ s: String) {
print(s)
}
completeMe(takeAString)
takeAString
的生命周期已经是程序的生命周期;这里没有内存管理影响。
如果传入实例方法,内存管理与传入实例本身一样。
*通常,如果有可能失败,您要么 a) 有第二个 "failure" 完成,要么 b) 完成将通过其参数表示失败。
如果您从不调用完成处理程序会怎样?有没有什么副作用?我假设可能存在内存泄漏,但我找不到任何文档。
func completeMe(completionHandler: @escaping (String?) -> Void) {
return
}
由于参数命名为 completionHandler
,您的调用者将假定它会被执行,无论如何。
因此,为了回答您的问题,不会有任何固有的副作用,但它可以被视为一种不好的做法。
从根本上说,"completion handler" 没有什么特别之处。这只是一个功能。
如果你有函数:
func f() {
print("Hello, world")
}
你不调用它,会发生什么?好吧,什么都没有发生。
现在,这意味着什么?正如 rmaddy 提到的,如果函数 有 完成,调用者肯定期望调用该完成。 充其量 一个函数完成并且调用者不关心完成是否曾经 运行.*
是不寻常的想象一下,该函数由一个视图控制器调用,该视图控制器在调用之前启动一个 activity 指示器,然后在完成时停止该指示器。如果从未调用完成,则指标永远不会停止旋转。
基本上就是这样。 如果未调用完成,则其代码不会 运行。其效果完全取决于完成期间和周围代码中发生的事情。
好的,你提到了内存...很多时候,完成处理程序将是一个匿名函数。在那种情况下,是一个创建的对象。但它与任何其他对象都遵循相同的内存管理规则。没有泄漏 只是因为 它没有被调用。如果 completeMe
看起来像这样:
func completeMe(_ completionHandler: (String) -> Void) {
completionHandler("Hello, world")
}
你这样称呼它:
completeMe({ self.detailLabel.text = [=12=] })
然后为匿名函数创建的对象不会在 completeMe
returns 之后存活。如果你存储匿名函数:
func completeMe(_ completionHandler: @escaping (String) -> Void) {
self.handler = completionHandler
// Do other things
}
然后与任何其他对象一样发生同样的事情:匿名函数一直存在,直到 属性 被设置为另一个值 (同时假设没有其他对象有参考一下).
如果你传入一个命名函数,
func takeAString(_ s: String) {
print(s)
}
completeMe(takeAString)
takeAString
的生命周期已经是程序的生命周期;这里没有内存管理影响。
如果传入实例方法,内存管理与传入实例本身一样。
*通常,如果有可能失败,您要么 a) 有第二个 "failure" 完成,要么 b) 完成将通过其参数表示失败。