Swift如何全局修改struct值 RXSwift subscribe内赋值外部无输出怎么办
问题原因
- RXSwift发起的Moya网络请求是异步操作,
subscribe的闭包要等网络请求响应成功之后才会执行,给productsList.itemsList赋值的操作是晚于你调用printResult()的时机的,所以你调用打印方法的时候数组还是空的,自然没有输出。 - 注意排查代码拼写问题:你定义的打印方法名为
printReuslt(字母顺序错误),如果实际调用的是printResult会导致方法不生效,也会出现无输出的情况。 - 当前用全局静态变量存储列表数据的方式不够安全,多线程下可能存在读写异常,也不符合RXSwift响应式的使用习惯。
修复方案
方案1:基于现有逻辑调整调用时机
你需要等subscribe的成功闭包执行完成之后,再去读取数组、刷新UI,比如可以在赋值完成后再调用打印和collectionView刷新逻辑:
func getProducts() { storeRepo .getAllProducts() .subscribe { [weak self] result in productsList.itemsList = result // 数据赋值完成后再执行后续操作 self?.printReuslt() // UI操作需要切到主线程执行 DispatchQueue.main.async { self?.collectionView.reloadData() } } onError: { error in print(error.localizedDescription) }.disposed(by: disposeBag) }
注意闭包内加[weak self]避免循环引用。
方案2:改用RXSwift响应式绑定(更推荐)
不用全局变量存储,直接把请求返回的序列绑定到collectionView上,更符合RXSwift的使用规范,也能避免异步时机问题:
- 首先在控制器中定义响应式序列存储产品列表:
private let products = BehaviorSubject<[ProductItem]>(value: []) private let disposeBag = DisposeBag()
- 在
viewDidLoad中完成序列和collectionView的绑定:
products .bind(to: collectionView.rx.items(cellIdentifier: "你的Cell复用ID", cellType: 你的自定义Cell类.self)) { _, item, cell in // 按需给Cell控件赋值 cell.titleLabel.text = item.name cell.categoryLabel.text = item.category } .disposed(by: disposeBag)
- 请求成功后给序列发送数据即可,会自动触发列表刷新:
func getProducts() { storeRepo .getAllProducts() .subscribe { [weak self] result in self?.products.onNext(result) } onError: { error in print(error.localizedDescription) }.disposed(by: disposeBag) }
内容的提问来源于stack exchange,提问作者Ahmed Shawky
相关产品推荐
相关产品推荐

