完成处理程序从未调用

时间:2017-12-28 22:06:27

标签: swift swift4

我有这样的功能。

class func getAccountBalances(completionHandler:@escaping ((_ balances:Any) -> Void)){
//Alamofire request and we get the result. But sometimes the result fails.
    switch response.result {
    case .success(let value):
        completionHandler(value)
    case .failure(let error):
        print ("error is: \(error)")
}

如果失败,我不会把代码放到处理结果中。那是一件坏事?在调用失败的情况下,我是否需要有一个完成处理程序,以便此函数不会留在内存中等待调用完成处理程序?什么是最佳做法?

2 个答案:

答案 0 :(得分:0)

您的标题:完成处理程序从未调用

您的代码:如果出现错误,则不会向完成处理程序返回任何值。

如果出现故障,您希望如何看到竞争处理程序的结果?你想破解应用程序吗?这种方式更好,因为它处理两种情况:

class func getAccountBalances(completionHandler:@escaping ((_ balances:Any?) -> Void)){ //make Any an optional
//Alamofire request and we get the result. But sometimes the result fails.
    switch response.result {
    case .success(let value):
        completionHandler(value)
    case .failure(let error):
        print ("error is: \(error)")
        completionHandler(nil)
}

您对此功能的新调用:

getAccountBalances() { value in 
guard let _value = value else { // anticipate on the error return }
// use _value, the balances are inside.
}

另一种方法不是将其设为零,而是将其内部的价值向下转。这看起来像这样:

class func getAccountBalances(completionHandler:@escaping ((_ balances:Any) -> Void)){
//Alamofire request and we get the result. But sometimes the result fails.
    switch response.result {
    case .success(let value):
        completionHandler(value)
    case .failure(let error):
        print ("error is: \(error)")
        completionHandler(error) //notice this change
}

然后你的功能看起来像这样:

getAccountBalances() { value in 
if let error = value as? Error { //or whatever type your error is in the function
  //there is an error
}
}

答案 1 :(得分:0)

一般来说,最好在每个案例中都要求完成。这样做的原因是您通常希望让上方杠杆(业务逻辑层)决定是否应将某些余额(例如)标记为已保存,或者可能在发生错误时显示对话框。认为一切都应该是一个模块,这是一个很好的做法。话虽这么说,如果另一个模块想要在某个时刻调用相同的函数,那么让该模块结果发生了什么可能是个好主意。这可以用几种方式实现,我不会进入这里,这是你的决定。

但是,这不是必须的。如果一个块不会被调用,应该被释放,然后一切都是好记忆的。所以在你的例子中,如果你没有在其他地方保留块(例如将它保存在使getAccountBalances调用的类中的变量中),你应该没问题。

另一个重要的部分是当你调用函数时要注意不要在块中保留self而不创建内存泄漏:

getAccountBalances() { _ in 
   self.updateUI()
}

此块将创建一个自我保留,如果一切正常,但用户离开了屏幕,您可能最终使用已解除分配的变量并使应用程序崩溃。这里的一个好习惯是不在回调中保留自我,但在此之前使其变弱:

getAccountBalances() { [weak self] _ in 
   // This is not necessarily needed, and you could use self?.updateUI() instead. 
   // However, this is usually another thing i like to do and consider it a good practice
   guard let `self` = self else { return }
   self.updateUI()
}