使用 alamofire 实现 api 调用时出现问题

Having issue in implement api calling using alamofire

提问人:Muhammad Bilal Raza 提问时间:11/3/2023 最后编辑:RobMuhammad Bilal Raza 更新时间:11/4/2023 访问量:55

问:

我正在使用 alamofire 使用循环 web 3 调用,但问题是我更改了链,然后在 web3 调用中使应用程序崩溃。凸轮,您解决了这个问题,或者有人帮助我进行新的 api 调用,然后之前所有异步调用都停止了,然后提出了新的请求?此行中的问题:如何解决此并发调用?group.addTask { return await web3wrapper.shared }

func processHistoryDetails(historyDetail: History) async -> [String: Any]? {
    let logHistoryCount = historyDetail.logHistory?.count ?? 0
    var processWeb3Call: [String: Any]?
    await withTaskGroup(of: [String: Any]?.self) {[weak self] group in
        guard let self = self else {return}
        for i in 0 ..< logHistoryCount {
            let firstIndexDecodedEventParams = historyDetail.logHistory?[i].decodedEvent?.params?.firstIndex(where: { event in
                event.name == "value"
            }) ?? -1
            if firstIndexDecodedEventParams != -1 {
                let contractAddress = historyDetail.logHistory?[i].address
                let value = historyDetail.logHistory?[i].decodedEvent?.params?[firstIndexDecodedEventParams].value ?? "0"
                group.cancelAll()
                group.addTask {
                    return await Web3Wrapper.shared.processValue(contractAddress: contractAddress!, value: value, chainId: self.activeChain.chainId, rpcUrl: self.activeChain.rpcUrl)
                }
            }
        }
        for await result in group {
            if let result = result {
                processWeb3Call = result
            }
        }
    }
    return processWeb3Call
}

enter image description here

Swift 异步 async-await uikit

评论

0赞 Joakim Danielson 11/3/2023
当它崩溃时,你会遇到什么错误,你知道是哪一行导致崩溃吗?
0赞 Larme 11/3/2023
为什么会有 ?如果发生崩溃,控制台中是否有错误消息?你变了吗?以前的(据说有效的)代码是什么?group.cancelAll()
0赞 Muhammad Bilal Raza 11/3/2023
我附上了图片,您可以点击图片并指导我如何解决这个问题吗?我尝试了group.cancell,但问题是内存泄漏@Larme

答:

0赞 Rob 11/4/2023 #1

这里有很多可能的改进(简化为;去掉逻辑;捕获模式没有按照你认为的那样做;等等),但让我们把重点放在“启动一堆异步请求,但取消所有先前的请求,只保存最后一个请求的结果”上。if let foo = foo {…}if let foo {…}-1[weak self]

取消组后添加任务的想法是行不通的,因为正如文档所说,“如果您在取消组后将任务添加到组,则该任务在添加到组后会立即取消。

因此,如果意图真的不是同时运行这些多个请求,而是取消除最后一个请求之外的所有请求,我建议:

  1. 假设只有一个任务会实际运行,确定那个任务,然后只启动它,甚至根本不启动所有其他任务;因此
  2. 完全停用任务组模式,因为这只有在您确实想同时运行多个任务时才有意义。

例如,您可以以相反的顺序遍历日志历史记录,确定通过您想要的任何条件的日志历史记录,然后只返回该日志历史记录,而不是同时启动一堆您想要取消的任务:

func processHistoryDetails(historyDetail: History) async -> [String: Any]? {
    guard let logHistory = historyDetail.logHistory else { return nil }
    
    for log in logHistory.reversed() {
        if
            let param = log.decodedEvent?.params?.first(where: { $0.name == "value" }),
            let address = log.address
        {
            return await Web3Wrapper.shared.processValue(
                contractAddress: address, 
                value: param.value ?? "0", 
                chainId: activeChain.chainId, 
                rpcUrl: activeChain.rpcUrl
            )
        }            
    }
    
    return nil
}

综上所述,这种“将任务添加到已取消的组”很有可能不是崩溃的根源。更可能的候选者是强制解包运算符 。如果该可选是 ,则应用程序将崩溃。或 总是更好。因此,我没有强制解开地址,而是将其添加到子句中。(另外,我不知道这些其他变量是否是隐式解包的可选变量,但如果是这样,那就是另一个潜在的问题来源。!nilguard letif letif let

无论如何,这个主题有很多排列,但这个想法是无论如何都不要启动你要取消的任务,并避免强制解开可选选项。