【问题标题】:Optional Completion Handler with no parameters没有参数的可选完成处理程序
【发布时间】:2018-07-25 12:36:53
【问题描述】:

我基本上想要一个可选的完成处理程序,它没有传回的参数。这是我到目前为止所拥有的,但显然这是错误的。

func refreshAccountData(type:String, completion: (()->(Void))?){
    //Network call is made
    Alamofire.request... {
        completion?()
        //Here is where I want to call the optional completion handler
    }

}

我不想在完成块中传递任何参数。我只想知道网络调用何时完成,以便刷新 UI。我不想在这里刷新 UI,因为我希望它充当刷新数据的通用函数。我希望完成处理程序是可选的原因是因为有时我在刷新完成后不需要做任何事情。

我也很困惑@escaping 的含义。当我做这样的事情时,我通常会拥有它,但任何清晰都会很棒。我在网上做了一些关于它的功课,但没有找到我真正得到的东西。

【问题讨论】:

  • 这有什么问题?这并不明显,我只是使用了相同的声明而没有编译器错误..
  • 真的吗?这是最好的方法吗?我不必担心与转义有关的任何事情,也无需强制打开 completion?()。我相信 Xcode 让我解开 completion!()
  • 为什么不简单地func refreshAccountData(type:String, completion: @escaping ()->()){ 直接打电话给completion()?如果您不想执行任何操作,只需在调用您的方法时传递一个空闭包
  • 另一种选择是为你的完成处理程序设置一个默认值,这样你就可以在调用你的方法时简单地省略闭包func refreshAccountData(type:String, completion: @escaping (()->()) = {}){

标签: swift swift4


【解决方案1】:

首先,将Void 周围的括号去掉:

func refreshAccountData(type:String, completion: (() -> Void)?){
    //Network call is made
    Alamofire.request... {
        completion?() 
    }
}

如果你强制打开一个闭包调用,你基本上是在说你知道总会有一个完成回调。但在你的情况下,你明确提到你想要一个可选的,所以调用 completion?() 是你想要的。

关于转义,可选闭包被隐式转义,所以如果你想要一个非转义版本,你必须使用非可选闭包。阅读docs 中的转义闭包部分以了解有关转义的更多信息。基本上,在您的情况下,您需要一个转义闭包,因为您在异步回调中使用completion,它在refreshAccountData 完成后执行。但是,正如我所说,将闭包设为可选会使其隐式转义(在SO question 中阅读更多内容)。

现在您知道您的 completion 正在逃逸 - 这是什么意思?简单地说,如果它是非转义的,编译器将保证completion闭包在refreshAccountData方法完成后被释放,因此实际上completion捕获的所有资源也将被释放。然而,转义completion 闭包可以比refreshAccountData 调用期间的寿命更长——这意味着它可以创建保留周期(闭包可能会保持对self 和其他对象的实时强引用,这可能是因为保留了) .

现在,在您的情况下,既然您想要一个可选的 completion 闭包,那么除了简单地接受它正在转义之外,您别无他法 - 那么您如何确保 completion 闭包不会保留不需要的强引用?您可以在创建完成时简单地使用捕获列表(请参阅 this 以获取参考),以确保即使 self 也只是一个弱引用,并且不会因为关闭而被保留:

refreshAccountData(type: "") { [weak self] in
    guard let self = self else { return }
    self.doSomething()
}

【讨论】:

    猜你喜欢
    • 2014-10-06
    • 2019-01-31
    • 2012-01-06
    • 1970-01-01
    • 2014-05-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    相关资源
    最近更新 更多