1

我正在查询通知设置值,但我想知道是否[weak self]有必要。

有人请澄清:

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
    }
}
4

1 回答 1

2

如果[weak self]捕获列表的目的是防止强引用循环,那么,不,没有必要。这个getNotificationSettings闭包是异步调用的,它的闭包(以及任何被它捕获的东西)都会被快速释放,因此闭包引入的任何强引用都会被快速解决。

但是,如果您曾经[weak self]避免在异步任务运行时不必要地保持强引用(例如,在self此闭包运行之前关闭的不太可能的情况下),那么,是的,weak引用是谨慎的。如果闭包的唯一目的是更新可能不再可见的控件,那么保持强引用是没有意义的。

有人可能会争辩说,这[weak self]也是谨慎的,因为可以看一眼代码并立即确定没有引入强引用循环。您不必浪费任何时间推理通知中心 API;您会立即看到没有强参考周期风险。任何时候你可以一目了然地推断你的代码,这是一件好事。

简而言之,[weak self]捕获列表不是必需的,而是谨慎的。


两个不相关的观察:

  1. 我将消除[self]调度到主队列中的捕获列表。捕获列表的整个想法[self]允许self闭包内的隐式引用,因为使用的意图self已经被声明。

    但这是在 的[weak self]闭包内,无论如何getNotificationSettings您都在使用self?.可选的链接语法。[self]捕获列表不仅没有实际意义,而且只会向代码的未来读者发送相互矛盾的消息。我将删除[self]调度到主队列的捕获。

  2. 如果您关于消除[weak self]捕获列表的问题是出于简化代码的意图,我会保留weak捕获,但简化其余部分:

    UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in
        DispatchQueue.main.async {
            self?.vu.isEnabled = settings.authorizationStatus == .authorized
        }
    }
    
于 2021-09-08T20:07:10.753 回答