【问题标题】:Swift: Deadlock with DispatchGroupSwift:与 DispatchGroup 的死锁
【发布时间】:2017-10-12 21:00:53
【问题描述】:

我在 CoreData 并发方面遇到了一些问题。 当目标线程被DispatchGroup 阻塞时,我无法执行context.perform

这是一个显示问题的简单示例:

func upload(objects: [NSManagedObject]) {
    let group = DispatchGroup()
    for object in objects {
        group.enter()
        upload(object) {
            group.leave()
        }
    }
    group.wait()    // current thread is blocked here

    someAdditionalWorkToDoInSameThread()
}

func upload(object: NSManagedObject, completion: ()->()) {
    let context = object.managedObjectContext
    performAlamofireRequest(object) {
        context.perform {
            // can't reach here because the thread is blocked
            update(object)
            completion()
        }
    }
}

请帮助我正确地重新实现它。谢谢。

【问题讨论】:

    标签: ios swift core-data concurrency grand-central-dispatch


    【解决方案1】:

    在调度组上使用notify 而不是等待,应该可以解决您的问题。

    调用wait() 会阻塞当前线程以完成之前提交的工作。
    notify(queue:execute:) 将通知队列您作为参数传递的组任务已完成。

    func upload(objects: [NSManagedObject], completion: ()->()) {
        let group = DispatchGroup()
        for object in objects {
            group.enter()
            upload(object) {
                group.leave()
            }
        }
        group.notify(queue: DispatchQueue.main) {
             completion()
        }
    }
    

    【讨论】:

    • 应该这样做 ;) 顺便说一句,他原来的 update 函数在明显同步的函数上使用了不必要的 完成块。对我来说没有多大意义......
    • @AndriyTrubchanin:使用 notify 没有解决您的问题?
    • @Puneet Sharma 使用通知解决了我的问题。代码变得更加复杂,我搜索了使它更简单的方法。无论如何它都有效,谢谢。
    • @AndriyTrubchanin:很乐意提供帮助。您可以将现有代码分解为相关函数并从其他函数中调用它们。
    • @PuneetSharma 我也有类似的情况,但不起作用。 paste.ubuntu.com/p/cs2XYj6gdD ...这仅在我没有 Apple id 来测试订阅时第一次发生,之后,它在重新启动应用程序时起作用。我不明白为什么它第一次不处理完成处理程序?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 2013-02-22
    • 2019-03-19
    • 2014-10-09
    • 1970-01-01
    相关资源
    最近更新 更多