首页 > 解决方案 > 在异步队列中快速设置崩溃

问题描述

我在下面的异步队列关闭中使用时发现了奇怪的崩溃Set,确认它只发生在异步队列中,但Array有效。


func testA1() {
    var set = Set<Int>()

    for i in 0...10 {
        DispatchQueue.global().async {
            set.update(with: i) // Crash here: EXC_BAD_ACCESS
            // set.insert(i)
        }
    }

    print(set as Any)
}

func testA2() {
    var set = Set<Int>()

    for i in 0...10 {
        DispatchQueue.global().sync {
            set.update(with: i) // Works!
        }
    }

    print(set as Any)
}

func testB() {
    var array = [Int]() // Works!

    for i in 0...10 {
        DispatchQueue.global().async {
            array.append(i)
        }
    }

    print(array as Any)
}

斯威夫特版本:

Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
Target: x86_64-apple-darwin20.2.0

我的错误或快速错误?为什么?

标签: iosswiftasynchronoussetdispatch-async

解决方案


Swift 中的大多数数据类型都不是线程安全的。您应该使用不同的方式进行交互。

protocol ThreadSafeExecutor {
    var semaphore: DispatchSemaphore { get set }
    func wait()
    func signal()
}

extension ThreadSafeExecutor {
    func wait() {
        semaphore.wait()
    }
    func signal() {
        semaphore.signal()
    }
}


class YourClass: ThreadSafeExecutor { 
func someMethod() {
        wait()
        defer {
            signal()
        }
        /// thread-safe code
    }
}

推荐阅读