【问题标题】:Completion Handler Call N times完成处理程序调用 N 次
【发布时间】:2021-06-04 10:34:42
【问题描述】:

在Button动作中,我调用getLatLongValues方法,API成功后会返回completion属性。

听说问题是,如果我在按钮操作中单击 N 次,getLatLongValues 方法会执行 N 次。
就像我在第一次点击按钮 getLatLongValues 执行 1 次一样,我点击第二次而不是两次 getLatLongValues 方法执行 2 次。

@IBAction func updateDeliveryAddress() {
    guard let address = self.addressTextField.text else { return }
    self.getLatLongValues(address, true, viewModel) { success in
        if success {
            //Success
        } else {
            // Error
        }
    }
}

func getLatLongValues(address: String, setAsDefault: Bool, viewModel:ViewModel, completion: @escaping (_ success: Bool) -> Void) {
    viewModel.location.subscribe(onNext: { [weak self] results in
        guard self != nil else { return }
        if let result = results {
                completion(true) // Success
        }
    }).disposed(by: disposeBag)
    viewModel.fetchLocation(address: address)
}

为什么getLatLongValues 执行N次?

【问题讨论】:

  • 每次按下按钮时都会调用该函数。因此,函数中的所有内容,包括完成处理程序,都会被处理。
  • 你在用什么 coreLocations?
  • @TusharSharma 不,谷歌地理编码 API

标签: ios swift swift5 rx-swift completionhandler


【解决方案1】:

因为每次您都在创建新订阅。 订阅不是执行一次的完成处理程序。

viewModel.location.subscribe(onNext: { [weak self] results in

应该只被调用一次,并且在每次位置更新时,您都会在块中获得结果

【讨论】:

    【解决方案2】:

    如果你希望完成处理程序只被调用一次,你应该设置一个标志:

    var completionHandlerExecuted = false /// false at first
    
    func getLatLongValues(address: String, setAsDefault: Bool, viewModel:ViewModel, completion: @escaping (_ success: Bool) -> Void) {
        
        if completionHandlerExecuted == false {
            completionHandlerExecuted = true /// set to true, so it won't be called again
    
    
            viewModel.location.subscribe(onNext: { [weak self] results in
                guard self != nil else { return }
                if let result = results {
                    completion(true) // Success
                }
            }).disposed(by: disposeBag)
            viewModel.fetchLocation(address: address)
        }
    
    }
    

    完成处理程序与您在函数中放入的任何其他指令一样。

    每次调用getLatLongValues 时,您都在执行subscribe,它会在完成后调用完成处理程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-18
      • 2013-05-17
      • 2014-08-16
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多