You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何等待已启动的NetworkHandler初始化异步加载函数完成?

解决NetworkHandler初始化加载完成的监听问题

这是个很常见的异步状态同步场景,我给你几个从简单到优雅的解决方案,你可以根据项目的iOS版本复杂度来选择:


方案1:闭包回调(轻量直接)

直接在NetworkHandler的初始化方法里传入加载完成的回调,这样创建实例时就能绑定后续逻辑,不需要依赖本地变量判断:

class NetworkHandler {
    private(set) var initialLoadIsDone = false
    
    // 初始化时传入加载完成回调
    init(onInitialLoadComplete: (() -> Void)?) {
        loadData(completion: onInitialLoadComplete)
    }
    
    private func loadData(completion: (() -> Void)?) {
        // 模拟异步加载逻辑
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) { [weak self] in
            self?.initialLoadIsDone = true
            // 回到主线程执行UI操作
            DispatchQueue.main.async {
                completion?()
            }
        }
    }
}

ViewController中的用法:

class ViewController: UIViewController {
    var networkHandler: NetworkHandler?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        showLoadingIndicator()
        
        // 创建实例时绑定完成回调
        networkHandler = NetworkHandler { [weak self] in
            self?.hideLoadingIndicator()
            self?.showContent()
        }
    }
    
    private func showLoadingIndicator() {
        // 展示加载指示器的逻辑
    }
    
    private func hideLoadingIndicator() {
        // 隐藏加载指示器的逻辑
    }
    
    private func showContent() {
        // 展示正常界面的逻辑
    }
}

方案2:Combine响应式(iOS 13+ 推荐)

如果你的项目支持iOS 13及以上,用Combine框架来发布状态变化会更优雅,适合复杂的状态监听场景:

import Combine

class NetworkHandler {
    private(set) var initialLoadIsDone = false
    // 定义一个发布者,用于发送加载完成事件
    let initialLoadComplete = PassthroughSubject<Void, Never>()
    
    init() {
        loadData()
    }
    
    private func loadData() {
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) { [weak self] in
            guard let self = self else { return }
            self.initialLoadIsDone = true
            // 发送完成事件
            self.initialLoadComplete.send()
            self.initialLoadComplete.send(completion: .finished)
        }
    }
}

ViewController中的订阅逻辑:

class ViewController: UIViewController {
    var networkHandler: NetworkHandler?
    private var cancellables = Set<AnyCancellable>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        guard let handler = networkHandler else { return }
        
        if handler.initialLoadIsDone {
            showContent()
        } else {
            showLoadingIndicator()
            // 订阅加载完成事件,自动切换到主线程
            handler.initialLoadComplete
                .receive(on: DispatchQueue.main)
                .sink { [weak self] in
                    self?.hideLoadingIndicator()
                    self?.showContent()
                }
                .store(in: &cancellables)
        }
    }
    
    // 省略showLoadingIndicator等方法
}

方案3:Delegate模式(传统可靠)

如果需要兼容更低版本iOS,或者习惯用Delegate解耦逻辑,可以定义一个协议来传递加载完成事件:

// 定义代理协议
protocol NetworkHandlerDelegate: AnyObject {
    func networkHandlerDidFinishInitialLoad(_ handler: NetworkHandler)
}

class NetworkHandler {
    private(set) var initialLoadIsDone = false
    weak var delegate: NetworkHandlerDelegate?
    
    init() {
        loadData()
    }
    
    private func loadData() {
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) { [weak self] in
            guard let self = self else { return }
            self.initialLoadIsDone = true
            // 回到主线程通知代理
            DispatchQueue.main.async {
                self.delegate?.networkHandlerDidFinishInitialLoad(self)
            }
        }
    }
}

ViewController实现代理:

class ViewController: UIViewController, NetworkHandlerDelegate {
    var networkHandler: NetworkHandler?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        networkHandler?.delegate = self
        
        if networkHandler?.initialLoadIsDone == true {
            showContent()
        } else {
            showLoadingIndicator()
        }
    }
    
    // 实现代理方法
    func networkHandlerDidFinishInitialLoad(_ handler: NetworkHandler) {
        hideLoadingIndicator()
        showContent()
    }
    
    // 省略其他方法
}

方案选择建议

  • 如果是小型项目或快速迭代,闭包回调最直接轻量;
  • 如果项目已经使用Combine或需要处理复杂状态流,Combine方案是最优雅的选择;
  • 如果需要兼容iOS 12及以下,或者团队习惯用Delegate模式,Delegate方案更可靠。

内容的提问来源于stack exchange,提问作者Sonius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:12:50