闭包内执行Segue,EthViewController标签赋值BTC值不生效问题
解决BTC数值更新EthViewController标签无反应的问题
我来帮你梳理下问题所在,以及对应的解决办法:
核心问题分析
你遇到的视图不更新问题,大概率是两个原因导致的:
- UI更新不在主线程:
URLSession.shared.dataTask的闭包是在后台线程执行的,iOS要求所有UI操作必须在主线程完成,直接在后台线程设置标签内容不会触发视图刷新。 - 操作了错误的视图控制器实例:如果你是直接新建了
EthViewController的实例来设置标签,而不是获取当前屏幕上正在显示的那个实例,那更新的只是内存里的新对象,不会反映到界面上。
修复步骤及代码示例
1. 补全网络请求并确保UI更新在主线程
先把你的btcValue函数补全,同时加上主线程切换的逻辑,还要记得启动网络任务:
func btcValue(completion: @escaping((String) -> ())){ guard let url = URL(string: "https://api.coindesk.com/v1/bpi/currentprice.json") else { completion("无效URL") return } let task = URLSession.shared.dataTask(with: url) { (data, response, error) in if let error = error { print("获取BTC价格出错: \(error.localizedDescription)") completion("获取失败") return } guard let content = data else { print("未接收到数据") completion("无数据") return } do { // 完整解析JSON数据 if let json = try JSONSerialization.jsonObject(with: content, options: []) as? [String: Any], let bpi = json["bpi"] as? [String: Any], let usdData = bpi["USD"] as? [String: Any], let rate = usdData["rate"] as? String { // 切换到主线程执行UI更新操作 DispatchQueue.main.async { completion(rate) } } else { completion("解析失败") } } catch { print("JSON解析错误: \(error.localizedDescription)") completion("解析失败") } } task.resume() // 必须启动任务,否则闭包永远不会执行 }
2. 正确获取EthViewController实例并更新标签
要确保你操作的是当前屏幕上显示的EthViewController实例,举两种常见场景的实现方式:
// 在合适的位置调用btcValue函数,比如当前视图控制器的viewDidLoad btcValue { [weak self] btcRate in // 场景1:EthViewController是导航栈的顶部控制器 if let ethVC = self?.navigationController?.topViewController as? EthViewController { ethVC.yourPriceLabel.text = btcRate // 替换成你实际的标签变量名 } // 场景2:如果是通过segue跳转,可以提前保存实例引用 // 比如在prepare(for:sender:)方法中: // override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // if let ethVC = segue.destination as? EthViewController { // self.ethViewController = ethVC // } // } // 然后在这里直接使用保存的实例: // self?.ethViewController?.yourPriceLabel.text = btcRate }
额外注意事项
- 用
[weak self]捕获self,避免循环引用导致内存泄漏。 - 解析JSON时尽量用可选绑定,不要用强制解包,防止程序崩溃。
- 如果是用闭包或代理传值的方式更新视图,能更优雅地避免直接引用视图控制器,降低耦合度。
内容的提问来源于stack exchange,提问作者Aleksander Ficek
相关产品推荐
相关产品推荐

