【问题标题】:View Controller is not deinitialized when expected视图控制器未按预期取消初始化
【发布时间】:2020-09-23 03:49:39
【问题描述】:

我试图了解在 serial async DispatchQueue 中执行任务与通过 引用它在 方法/函数 中执行相同任务之间的区别>weak self 来自同一个 DispatchQueue

代码 - 1

asyncAfter 块在 1.5 秒后执行,而 task() 正在处理这会关闭视图控制器,但 deinit() 仅在 task() 之后调用完成了。

class NewViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.5, execute: {
            self.dismiss(animated: false, completion: nil)
        })

        let queue = DispatchQueue(label: "myQueue", qos: .default)

        queue.async {[weak self] in
            self?.task()
        }
    }

    private func task() {
        print("start")
        for i in 0...10000000 {
            if i%500 == 0 {

            }
        }
        print("stop")
    }

    deinit {
        print("deinit")
    }
}

控制台输出 = start stop deinit

代码 - 2

在这种情况下,deinit() 在视图控制器被关闭后按预期调用。

override func viewDidLoad() {
    super.viewDidLoad()

    DispatchQueue.main.asyncAfter(deadline: .now() + 1.5, execute: {
        self.dismiss(animated: false, completion: nil)
    })

    let queue = DispatchQueue(label: "myQueue", qos: .default)

    queue.async {[weak self] in
        print("start")
        for i in 0...10000000 {
            if i%500 == 0 {

            }
        }
        print("stop")
    }
}

deinit {
    print("deinit")
}

控制台输出 = 启动 deinit 停止

有人能解释一下为什么两者之间有区别吗?

【问题讨论】:

  • 请尝试在task()函数中分享print(Thread.current)的输出
  • @emrcftci 在task() 内的print(Thread.current) 输出是<NSThread: 0x60000092d480>{number = 4, name = (null)}

标签: ios swift xcode multithreading memory


【解决方案1】:

虽然两个闭包都使用weak self,但第一个闭包调用了视图控制器上的一个函数。这会导致视图控制器被保留,直到该函数返回。

如果不是,那么视图控制器将在函数仍在执行时被释放,这将是一件坏事

在第二个闭包中,没有对self 的引用,所以闭包只是由调度队列保留。

【讨论】:

  • 如果引用该方法的唯一事物是弱引用并且没有“强烈”持有它,为什么还要保留视图控制器?
  • 有一个对self 的隐式强引用,以防止对象在其代码执行时被释放。如果没有,那么就会发生崩溃,因为函数在运行时被拆除了
猜你喜欢
  • 2019-07-28
  • 1970-01-01
  • 2016-06-07
  • 2020-01-04
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
相关资源
最近更新 更多