Ios 完成处理程序调用N次

Ios 完成处理程序调用N次,ios,swift,swift5,rx-swift,completionhandler,Ios,Swift,Swift5,Rx Swift,Completionhandler,在按钮操作中,我调用getLatLongValues方法,它将在API成功后返回completion属性 问题是,如果我在按钮操作中单击第次,则执行方法的次数为getLatLongValuesN。 就像我第一次单击按钮一样,我要单击第二次而不是两次getLatLongValuesmethod执行两次 @IBAction func updateDeliveryAddress() { guard let address = self.addressTextField.text else {

在按钮操作中,我调用
getLatLongValues
方法,它将在API成功后返回completion属性

问题是,如果我在按钮操作中单击第次,则执行方法的次数为
getLatLongValues
N。
就像我第一次单击按钮一样,我要单击第二次而不是两次
getLatLongValues
method执行两次

@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次N次?

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

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

应该只调用一次,并且在每次位置更新时,都会在块中得到结果,因为每次创建新订阅时。 订阅不是执行一次的完成处理程序

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

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

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

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
,完成后将调用完成处理程序。

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

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
,完成后将调用完成处理程序。

每次按下按钮时,您都会调用该函数。因此,函数中的所有内容,包括完成处理程序,都会被处理。您在使用coreLocations做什么?@TusharSharma No,Google geocoding api每次按下按钮都会调用函数。因此,函数中的所有内容,包括完成处理程序,都会被处理。您使用的coreLocations是什么?@TusharSharma No,Google地理编码API