【问题标题】:Memory leak when adding subview添加子视图时内存泄漏
【发布时间】:2018-09-05 00:59:08
【问题描述】:

添加子视图时,视图控制器似乎泄漏。

为什么下面会打印'What'

import UIKit

final class ViewController: UIViewController {

    private lazy var mySwitch: UISwitch = {
        let mySwitch = UISwitch()
        mySwitch.tintColor = .blue
        return mySwitch
    }()

    func setup() {
        view.addSubview(mySwitch)
    }

    @objc func switchChangedState() {

    }

    deinit {
        print("what")
    }
}

var controller: ViewController? = ViewController()
controller = nil

但以下没有

var controller: ViewController? = ViewController()
controller?.setup()
controller = nil

编辑:添加 GIF

Xcode 版本 9.4.1 (9F2000)

【问题讨论】:

  • 为什么是最终的?
  • 嗨@TomSchulz。我出于习惯写final。在此特定示例中,不需要它。话虽如此,作为一种习惯,我还是建议您添加 final,直到您准备好支持子类化。
  • 不同意。无论如何,您都不能发布头文件和库。如果有人希望事情不是最终的,他们只需编辑您的代码。 '支持子类化';该语言支持子类化。
  • @TomSchulz 我不明白你所说的“发送头文件和库”或“只编辑你的代码”是什么意思。
  • @TomShulz 如果您还没有准备好支持子类化,我建议添加 final。当然,你和其他人可以在未来改变这种想法。当您准备子类化时更改它。此外,添加final是性能的提升。 developer.apple.com/swift/blog/?id=27

标签: ios memory-leaks


【解决方案1】:

你的代码很好。 controller?.setup() 不会导致泄漏。请确保测试用例 2 中的代码是否真的被调用。 (不调用不打印“什么”)

【讨论】:

  • 我支持这个 - 这里没有保留周期。当我构建并运行您的代码时,在这两种情况下都会调用反初始化器。
  • 嗨@PeteMorris。我同意,代码肯定表明这里没有保留周期,但我看到的行为表明并非如此。已添加 gif 来演示。
  • 您好@YunCHEN 已将 gif 添加到帖子中。
  • @Jonesy 这与操场有关,您的代码完全没有问题。也许它是一个错误,或者游乐场出于某种原因保留了您的控制器。如果你在一个实际的 Xcode 项目中运行完全相同的代码,反初始化器肯定会在这两种情况下运行:imgur.com/a/QkLn6Q3
  • 感谢@PeteMorris 将接受如果您将其作为官方答案
【解决方案2】:

您的代码没有问题。这里没有保留周期。

问题似乎与操场有关。这可能是一个错误,或者 Playground 可能出于某种原因保留了您的视图控制器。

如果您在实际的 Xcode 项目中执行代码(在 iOS 模拟器中或在设备上),则在两种情况下都会执行初始化程序:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 2011-03-07
    • 1970-01-01
    • 2012-08-23
    • 2016-08-10
    • 1970-01-01
    • 2011-12-24
    • 2023-01-20
    相关资源
    最近更新 更多