iosmemory-leaksunusernotificationcenterswift-block

Is Weak self required while fetching notification settings of the app


I'm querying notification settings value but I wonder whether [weak self] is necessary.

Someone kindly clarify:

UNUserNotificationCenter.current().getNotificationSettings { [weak self] appsettings in
    var mybool = false
    if appsettings.authorizationStatus == .authorized {
        mybool = true
    }
    DispatchQueue.main.async { [self] in
        self?.vu.isEnabled = mybool
    }
}

Solution

  • If the intent of the [weak self] capture list was to prevent a strong reference cycle, then, no, that is not necessary. This getNotificationSettings closure is called asynchronously and its closure (and anything captured by it) is quickly released, so any strong references introduced by the closure are quickly resolved.

    If, however, you used [weak self] to avoid unnecessarily keeping a strong reference while the asynchronous task is running (e.g., in the unlikely case that self is dismissed before this closure runs), then, yes, the weak reference is prudent. There is no point in keeping a strong reference if the sole purpose of the closure is to update a control that may no longer be visible.

    One could argue that the [weak self] is also prudent because one can glance at the code and immediately determine that no strong reference cycle is introduced. You do not have to waste any time reasoning about the notification center API; you immediately see that there is no strong reference cycle risk. Any time you can reason about your code at a glance, that is a good thing.

    In short, the [weak self] capture list is not necessary, but is prudent.


    Two unrelated observations:

    1. I would eliminate the [self] capture list in the dispatch to the main queue. The whole idea of the [self] capture list is to allow implicit self references inside the closure now that the intent to use self has been declared.

      But this is inside the [weak self] closure of getNotificationSettings, and you are using the self?. optional chaining syntax, anyway. The [self] capture list not only moot, but only sends contradictory messages to future readers of your code. I would remove [self] capture for the dispatch to the main queue.

    2. If your question about eliminating the [weak self] capture list is motivated by an intent to simplify the code, I would keep the weak capture, but simplify the rest:

      UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
          DispatchQueue.main.async {
              self?.vu.isEnabled = settings.authorizationStatus == .authorized
          }
      }