永不调用函数的完成处理程序有什么影响?

时间:2019-01-25 21:47:49

标签: swift completionhandler

如果您从不调用完成处理程序,会发生什么?有没有什么副作用?我假设可能存在内存泄漏,但是找不到任何文档。

func completeMe(completionHandler: @escaping (String?) -> Void) {
   return
}

2 个答案:

答案 0 :(得分:2)

由于参数名为completionHandler,因此您的调用者将假定它将被执行,无论如何。

因此,要回答您的问题,不会有任何固有的副作用,但这可能被认为是不好的做法。

答案 1 :(得分:2)

从根本上讲,“完成处理程序”没有什么特别的。这只是一个功能。

如果您有功能:

func f() {
    print("Hello, world")
}

您不叫它,那会发生什么?好吧,什么都没发生

现在,这意味着什么?正如rmaddy所提到的,如果函数具有完成,则调用者当然希望调用该完成。 充其量是不常见的,因为一个函数需要一个补全,而调用者却不在乎是否已运行补全。

想象一下,该函数是由视图控制器调用的,它在调用之前启动活动指示器,然后在完成时停止该指示器。如果从未调用完成,则指示器永远不会停止旋转。

基本上就是这样。 如果未调用完成功能,则其代码将无法运行。效果完全取决于完成中及其周围代码的作用。


好的,您提到了内存...很多时候,完成处理程序将是一个匿名函数。在这种情况下,将创建一个 对象。但是它与其他任何对象都受相同的内存管理规则约束。没有泄漏只是因为没有被调用。如果completeMe看起来像这样:

func completeMe(_ completionHandler: (String) -> Void) {
    completionHandler("Hello, world")
}

您这样称呼它:

completeMe({ self.detailLabel.text = $0 })

然后,当completeMe返回时,为匿名函数创建的对象将不存在。如果您存储匿名函数:

func completeMe(_ completionHandler: @escaping (String) -> Void) {
    self.handler = completionHandler
    // Do other things
}

然后发生与其他任何对象相同的事情:匿名函数将一直存在,直到该属性设置为另一个值 (也要保证没有其他引用)

如果您传入一个命名函数,

func takeAString(_ s: String) {
    print(s)
}

completeMe(takeAString)

takeAString的生存期已经是程序的生存期;这里没有内存管理的含义。

如果传入实例方法,则内存管理与传入实例本身相同。


*通常,如果可能发生故障,您将a)进行第二次“失败”完成,或者b)完成将通过其参数来表示失败。