dispatch_async更新变量崩溃 - 线程安全

时间:2016-07-01 08:53:02

标签: swift grand-central-dispatch dispatch-async

当我多次运行以下代码时,应用程序崩溃在该行:

res.append(I)

错误是致命错误:UnsafeMutablePointer.destroy有负数 要么  正在释放的指针未分配***在malloc_error_break中设置断点以进行调试

更新dispatch_async中的全局变量是不正确的?

类ViewController:UIViewController {

var result = Array<Int>()


func method(completion: (inner: () throws -> String)->Void){
    let group:dispatch_group_t = dispatch_group_create();
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    var res = Array<Int>()
    for i in 0..<4 {
        dispatch_group_async(group,queue){
            res.append(i)
            print(res)
            print("Block\(i)");                
            var s = 0
            for k in 0..<1000 {
                s = 2+3
            }
            print("Block\(i)End");



        }
    }

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    print("All background tasks are done!!");
    print(res)
}


override func viewDidLoad() {
    super.viewDidLoad()


    self.method() { (inner: () throws -> String) -> Void in
        do {
            let res = try inner()
            print(res)
        } catch let error {
            print(error)
        }
    }
}

1 个答案:

答案 0 :(得分:1)

是的,Array不是线程安全的,所以在写入数组时,应该确保atomic

所以你可以添加高性能锁:dispatch_semaphore_t。

func method(completion: (inner: () throws -> String)->Void){
    //  add lock
    let lock: dispatch_semaphore_t = dispatch_semaphore_create(1)
    let group:dispatch_group_t = dispatch_group_create();
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    var res = Array<Int>()
    for i in 0 ..< 5 {
        dispatch_group_async(group,queue){
            // lock
            dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)
            res.append(i)
            // unlock
            dispatch_semaphore_signal(lock)
            var s = 0
            for k in 0..<1000 {
                s = 2+3
            }
        }
    }

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    print("All background tasks are done!!");
    print(res)
}

但要小心,如果您的异步任务不像上面那样耗时,请不要使用多线程,因为线程调度很耗时,可能会导致性能下降。