title: DispatchGroup [weak self] handling in nested notify
body: <p>I have two asynchronous functions. I need to run second function based on first's output and run third function after second is complete. I did it like this. Is it correct way to handle serialization? And how to handle weak self reference?</p>
  
  <pre><code>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
      }
  }
  </code></pre>