嵌套Dispatch Group内部notify回调未触发问题求助
问题分析与解决方案
为什么嵌套的notify无法触发?
你嵌套写法里的核心问题大概率是**self提前被释放**:因为你用了[weak self],当dispatchGroupOne的notify回调执行时,如果self已经被销毁,self?.dispatchGroupTwo就会变成nil,导致后续的notify调用直接被忽略,自然不会触发内部的回调。
另外补充:即使self存在,如果dispatchGroupTwo已经处于完成状态(比如从未调用过enter/leave,或者所有leave都已执行完毕),理论上notify的回调应该会被异步调度到主队列,但这种场景下嵌套写法本身就不是实现“两个Group都完成后执行代码”的正确方式。
实现两个Dispatch Group都完成后执行代码的正确方式
要等两个Group全部完成后再执行特定逻辑,最优雅的做法是用第三个Dispatch Group来监听前两个Group的完成事件,代码示例如下:
// 创建一个用于合并两个Group的新Group let combinedGroup = DispatchGroup() // 监听第一个Group的完成 combinedGroup.enter() dispatchGroupOne.notify(queue: .global(qos: .default)) { combinedGroup.leave() } // 监听第二个Group的完成 combinedGroup.enter() dispatchGroupTwo.notify(queue: .global(qos: .default)) { combinedGroup.leave() } // 两个Group都完成后,在主队列执行目标代码 combinedGroup.notify(queue: .main) { // 这里写你需要执行的逻辑 }
另一种简化写法(支持iOS 13+/macOS 10.15+)
如果项目部署版本支持Combine框架,也可以用Publishers将两个Group的完成事件合并:
import Combine // 将DispatchGroup的完成事件转为Publisher func groupCompletedPublisher(_ group: DispatchGroup) -> AnyPublisher<Void, Never> { return Future { promise in group.notify(queue: .global()) { promise(.success(())) } }.eraseToAnyPublisher() } // 合并两个Publisher,等待都完成后执行 Publishers.Zip(groupCompletedPublisher(dispatchGroupOne), groupCompletedPublisher(dispatchGroupTwo)) .receive(on: DispatchQueue.main) .sink { _ in // 这里写你需要执行的逻辑 } .store(in: &cancellables) // 需在类中定义var cancellables = Set<AnyCancellable>()
内容的提问来源于stack exchange,提问作者Tometoyou
相关产品推荐
相关产品推荐

