嵌套通知中的DispatchGroup [弱自我]处理

时间:2017-08-05 19:07:54

标签: swift swift3 grand-central-dispatch weak-references blockingqueue

我有两个异步函数。我需要根据第一个输出运行第二个函数,并在第二个函数完成后运行第三个函数。我是这样做的。这是处理序列化的正确方法吗?以及如何处理弱自我引用?

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()
function1() // async completion contains leave()

dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
    guard let strongSelf = self else {return}
    strongSelf.dispatchGroup.enter()    
    strongSelf.function2() // Also async, dependent on the result of function1. contains leave()

    strongSelf.dispatchGroup.notify(queue: DispatchQueue.main) {
        strongSelf????.function3()
        print("results of function1 and function2")
        // I must wait to finish first two tasks in order, in other words serial queue
    }
}

2 个答案:

答案 0 :(得分:1)

1)正确的方法:在前一个方法完成后调用方法

class SomeAsyncType {

    typealias SomeResultType = String

    func async(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
        self.asyncfunctionA(someDate, completion: completion)
    }

    private func asyncfunctionA(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
        DispatchQueue.main.async { [weak self] in
            sleep(1)
            print("ResultA")
            self?.asyncfunctionB("ResultA", completion: completion)
        }
    }

    private func asyncfunctionB(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
        DispatchQueue.main.async { [weak self] in
            sleep(2)
            print("ResultB")
            self?.asyncfunctionC("ResultB", completion: completion)
        }
    }

    private func asyncfunctionC(_ someDate: Any, completion: @escaping (SomeResultType) -> Void) {
       DispatchQueue.main.async {
            sleep(3)
            print("ResultC")
            completion("")
            print("All completed")
        }
    }
}

用法:

let test = SomeAsyncType() // hold reference 
test.async("noDate") { result in
    print(result)
}

控制台:

ResultA
ResultB
ResultC

All completed

2)如何处理弱自引用?

这是新范围,然后您可以再次使用[weak self]

dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
    guard let strongSelf = self else {return}
    strongSelf.dispatchGroup.enter()
    strongSelf.function2() // Also async, dependent on the result of function1. contains leave()

    strongSelf.dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
        guard let strongSelf = self else {return}
        strongSelf.function3()
        print("results of function1 and function2")
    }
}

答案 1 :(得分:0)

这取决于你的function1和2是什么,但我会考虑使用completionHandlerInstead:

function1(completionHandler: { [weak self] results in
   guard let strongSelf = self else {return} 

   if results == true //if it'd be bool
   {
      strongSelf.function2(completionHandler: { [weak self] results in
   guard let strongSelf = self else {return}

      //here you can get results from both if you want
      })
   }
   else
   {
   //false
   }
})