async/await, Task and [weak self]

0

Okay so we all know that in traditional concurrency in Swift, if you are performing (for example) a network request inside a class, and in the completion of that request you reference a function that belongs to that class, you must pass [weak self] in, like this:

func performRequest() {
   apiClient.performRequest { [weak self] result in
      self?.handleResult(result)
   }
}

This is to stop us strongly capturing self in the closure and causing unnecessary retention/inadvertently referencing other entities that have dropped out of memory already.

How about in async/await? I’m seeing conflicting things online so I’m just going to post two examples to the community and see what you think about both:

class AsyncClass {
   func function1() async {
      let result = await performNetworkRequestAsync()
      self.printSomething()
   }

   func function2() {
      Task { [weak self] in
         let result = await performNetworkRequestAsync()
         self?.printSomething()         
      }
   }

   func function3() {
      apiClient.performRequest { [weak self] result in
         self?.printSomething()
      }
   }

   func printSomething() {
      print("Something")
   }
}

function3 is straightforward – old fashioned concurrency means using [weak self].
function2 I think is right, because we’re still capturing things in a closure so we should use [weak self].
function1 is this just handled by Swift, or should I be doing something special here?