如何在参数超出范围的 Swift 中的单独代码块中编写完成处理程序

How to write a completion handler in a separated block of code in Swift with parameters out of scope

我试图让我的代码干净并解耦下面的代码,我想从中删除尾随的完成处理程序并将完成处理程序写在另一个代码块中。

func uploadMarcasMetodoNovo(_ id_resenha: Int) {
    
    let resenhaDados:ResDadoModel = db.readDadosResenhaById(id_resenha)
    let resenhaMarcas:[ResMarcasModel] = db.readResMarca(id_resenha)

    // this for loop runs about for 7 times                
    for marca in resenhaMarcas { 

        contadorUploadMarcas = contadorUploadMarcas + 1
        myUploadGroupMarcas.enter()
        
        jsonRequestUploadImagemGrafica = ResMarcasModel.createJsonMarcaResenha(marca, resenhaDados.IdGedave )
        
        let json: [String: Any] = jsonRequestUploadImagemGrafica
        guard let jsonData = try? JSONSerialization.data(withJSONObject: json) else {
            print("guard jsonData error")
            return
        }
        
        let requestImagemGrafica = requestUploadFotos(jsonData)
        let task = URLSession.shared.dataTask(with: requestImagemGrafica) { data, response, error in
            if let error = error {
                print("error: \(String(describing: error))")
                return
            }
            
            print("data")
            guard let returnData = String(data: data!, encoding: .utf8) else {
                print("returnData guard fail")
                return
            }
            print("returnData")
            print(returnData)
            
            self.confirmStatusEnviada(marca)
            self.myUploadGroupMarcas.leave()
            print("end TASK")
        }
        task.resume()
    }
    
    myUploadGroupMarcas.notify(queue: DispatchQueue.main) {
        print("myUploadGroupMarcas notify")
        // more code ...
    }
}

这是我编写的创建单独的完成处理程序的部分

let myCompletionHandler: (Data?, URLResponse?, Error?) -> Void = {
  (data, response, error) in
    if let error = error {
        print("error: \(String(describing: error))")
        return
    }
    
    print("data")
    guard let returnData = String(data: data!, encoding: .utf8) else {
        print("returnData guard fail")
        return
    }
    self.confirmStatusEnviada(marca)                
    self.myUploadGroupMarcas.leave()
    
}

但它不会工作,因为在最后两行代码中使用了超出范围的参数。参数“marca”和参数“myUploadGroupMarcas”超出范围。有没有办法在分离的完成处理函数中使用这些参数?

好的,根据我们上面的评论,这是我会尝试的路线:编写一个简短的完成处理程序来调用您的较长的完成处理程序,传递超出范围的变量。

let task = URLSession.shared.dataTask(with: requestImagemGrafica) { data, response, error in

myCompletionHandler(data, response, error, marca, myUploadGroupMarcas)

}

然后在函数定义中向完成处理程序添加两个参数:

let myCompletionHandler: (Data?, URLResponse?, Error?, MarcaClass, myUploadGroupMarcas) -> Void

显然,您需要将 MarcaClass 替换为实际的 class 类型,即 marca 并且 myUploadGroupMarcas 似乎是一个函数,因此您需要编写一个合适的参数类型。