ios - 像这样的 : 代码是否存在强保留问题

标签 ios swift

下面的代码中,self.tableView.reloadData()中的self是强引用有没有问题,是改成弱引用,还是照样可以?

class SomeViewController : UIViewController {
    fileprivate var notificationToken: NotificationToken?  = nil


...
    override func viewDidLoad()
    {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(onNotification), name: NSNotification.Name(SomeNotification), object: nil)

        realmNotificationToken = blockedList.observe({ (changes: RealmCollectionChange) in
            switch changes
            {
            case .initial:
                self.tableView.reloadData() // Case 1
                break
...


    @objc func onNotification()
    {
        DispatchQueue.main.async{
            self.tableView.reloadData() // Case 2
        }
    }

在这两个例子中,是否由于 self 是强引用而导致保留循环有任何问题,它应该更改为 weak? 在这两种情况下,使用 self.tableView.reloadData() 的两个 block 的生命周期是多少?如果生命周期是短暂的,那么使用 strong 就没有问题,不管这些 block 有多长?

最佳答案

情况 2 是非转义闭包,因此没有问题。

情况 1 是 @escaping,因此您需要使用 weakunowned 引用。 @escaping 意味着您将闭包传递给可能比创建闭包的对象(即您的 ViewController)更长寿的对象。如果您在 @escaping 中强烈捕获 self ,那么您的 ViewController 现在会在闭包存在时一直存在,并且闭包会一直存在,直到您取消订阅。如果您仅在 ViewController 取消初始化时取消订阅,那么您现在有一个循环。闭包永远不会被释放,因为订阅永远不会消亡,而 ViewController 永远不会消亡,因为订阅永远不会消亡。

编辑: 我应该补充一点,你实际上在任何一种情况下都不需要 self ;您可以简单地捕获 TableView (如果它被隐式解包,它将被脱糖成一个普通的可选,这很好):

realmNotificationToken = blockedList.observe({ [tableView] (changes: RealmCollectionChange) in
   switch changes {
   case .initial:
      tableView?.reloadData()

关于ios - 像这样的 : 代码是否存在强保留问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55364400/

相关文章:

ios - 下载图像无法在 IOS 设备上运行 - React Native

ios - 无法表达元组转换 '([Subclass], Int, String)' 到 '([Superclass], Int, String)'

ios - 用户界面设计类似于TableView

ios - 函数中具有相互递归关联类型约束的 Swift 协议(protocol)

swift - Swift 中 GKAgentDelegate 的协议(protocol)方法不对?

具有 throw init 行为的 swift lazy var

swift - 为什么只调用我的最后一个本地通知函数?

ios - 像 youtube 应用程序一样快速的 UISlider

ios - 我如何快速获取按钮的图像?

iphone - 当应用程序在后台时,每 5 分钟通过 iPhone 应用程序向服务器发送位置更新