在 iOS 13 上同步更新线程内的发布值时,Swift 崩溃

Posted

技术标签:

【中文标题】在 iOS 13 上同步更新线程内的发布值时,Swift 崩溃【英文标题】:Swift crashes when update published value inside a thread synchronously on iOS 13 【发布时间】:2022-01-11 14:11:27 【问题描述】:

我有几个步骤需要同步处理。并且该过程产生的值被视图消耗。它在 ios 14 上运行,但在 iOS 13 上崩溃。我使用组合来发布事件以更新存储在视图模型中的值。

这是 PublisherManager:

final class PublisherManager 
    static let shared = PublisherManager()
    private var cancellable = Set<AnyCancellable>()

    func mainPublisher() -> AnyPublisher<MainInput, Never> 
        mainSubject
            .eraseToAnyPublisher()
    

    let mainSubject = PassthroughSubject<MainInput, Never>()

    enum MainInput 
        case updateValue()
    

这是视图模型:

final class ViewModel: ObservableObject 

    @Published var status: Status = .checking

    init() 
        setObserver()
        start()
    

    private func setObserver() 
        PublisherManager.shared.mainPublisher()
            .receive(on: RunLoop.main)
            .sink  [weak self] action in
                guard let self = self else  return 
                switch action 
                case .updateValue:
                    self.updateValue()
                
            .store(in: &cancellable)
    

    func start() 
        let dispatchGroup = DispatchGroup()
        let dispatchSemaphore = DispatchSemaphore(value: 1)

        dispatchGroup.enter()
        dispatchQueue.asyncAfter(deadline: DispatchTime.now() + 1) 
            dispatchSemaphore.wait()
            self.getValues  //--> A process to call API
                PublisherManager.shared.pushNotificationTroubleshooterSubject.send(.updateValue())
                dispatchSemaphore.signal()
                dispatchGroup.leave()
            
        
        
        dispatchGroup.notify(queue: .main) 
            // Notify
        
    
    
    private func updateValue() 
        status = .active
    

当我运行它时,我在 AppDelegate 中得到了 EXC_BAD_ACCESS,但它在调试器上根本没有打印任何错误。如果我评论 status = .active 代码,它不会崩溃。

我做错了什么,我该如何解决这个问题?

【问题讨论】:

DispatchGroupDispatchSemaphore 强制异步任务变为同步是一种可怕的做法。尤其是在Combine 上下文中,这使得异步任务的处理非常方便。 DispatchGroup 无论如何都是错误的 API。它旨在控制循环中(多个)异步任务的中的时间。 @vadian 但是如何解决呢?我的意思是,我尝试使用dispatchQueue.sync,但它不起作用 正如我所说,Combine 提供了操作符来平滑地组合异步任务。 @vadian 嗯,恐怕我没听清楚,你能详细说明一下吗? 【参考方案1】:

看起来您对DispatchGroupDispatchSemaphore 所做的操作是错误的。 combine this 的概念类似于异步代码执行。因此,不要使用 DispatchGroupDispatchSemaphore,而是使用带有 combineLeates 的发布者链,并根据收到的事件执行操作

【讨论】:

答案不清楚,请编辑您的答案以添加一些细节,特别是一些描述工作流程的代码。请记住,该问题指定他需要对任务进行计时,以免超过每秒一次的 API 调用超载。

以上是关于在 iOS 13 上同步更新线程内的发布值时,Swift 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在同步方法中读取值时的安全发布

windows下mysql-8.0.13主从同步配置方案(读写分离)

windows下mysql-8.0.13主从同步配置方案(读写分离)

py知识(每日更新) 7.26

gj13 asyncio并发编程

UISplitViewController 内的 iOS 13 UITabBarController 未正确折叠