在单例类中是否需要使用弱引用?

3

我看到了一个来自raywenderlich的教程,作者提供了一些关于在单例中处理线程问题的好建议。但是当使用闭包时,他在单例类中使用了“弱引用循环”。因为该类是一个单例,所以它应该始终只有一个实例,真的需要这样吗?

    final class PhotoManager {
      private init() {}
      static let shared = PhotoManager()

      private var unsafePhotos: [Photo] = []

    let concurrentPhotoQueue = DispatchQueue(label: "com.jeesson.googlypuff.photoQueue", attributes: .concurrent)
      var photos: [Photo] {
        var photoCopy:[Photo]!    
        concurrentPhotoQueue.sync {
            photoCopy = self.unsafePhotos
        }
        return photoCopy
      }

      func addPhoto(_ photo: Photo) {

// Do we need 'weak self here.. and why?
        concurrentPhotoQueue.async(flags: .barrier) {[weak self] in
            // 1
            guard let self = self else {
                return
            }
            self.unsafePhotos.append(photo)
            DispatchQueue.main.async { [weak self] in
                //self?.postContentAddedNotification()
            }
        }



      }

    }

The tutorial


1
如果你不使用weak self,什么也不会发生。这只是一个好的习惯。 - Shreeram Bhat
2个回答

6

在使用 DispatchQueue 闭包时,请不要添加任何捕获列表。

DispatchQueue 闭包不会引起保留循环,因为 self 没有拥有它们。

基本上,在单例对象中不需要使用捕获列表,因为单例永远不会被释放。


由于单例永远不会被回收,那么如果单例在注销时需要被回收怎么办? - mfaani
@Honey “logout” 是什么意思? - vadian
退出应用程序。例如,您有一个单例执行刷新令牌的操作。在注销/退出登录时,该单例将不再需要。 - mfaani
@Honey,你不能使用标准的 static let shared = 属性来释放单例。如果你需要一个 易失性 实例,那么单例就不是正确的选择。 - vadian

1

有些单例的生命周期与应用程序的生命周期相关联。有些单例的生命周期与登录/注销相关联。

那么,如果单例在注销时需要被释放怎么办?我认为这是一个有效的情况,使用[weak self]可能很有用,即使对于单例也是如此。

否则,正如vadian所说,DispatchQueue闭包不会引起保留周期,因为self不拥有它们。欲了解更多,请参见此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接