为什么调用 super 是此方法的最后一件事而不是第一件事?

Why the call to super is the last thing on this method and not the first thing?

我边学边学Swift。

我找到了这样的函数 viewDidLoad() 并且许多其他函数有时是这样写的:

override func viewDidLoad() {
  super.viewDidLoad()
  // Do any additional setup after loading the view, typically from a nib.
}

有时这样写:

override func viewDidLoad() {
  // Do any additional setup after loading the view, typically from a nib.
  super.viewDidLoad()
}

我的意思是调用 super.viewDidLoad() 作为函数内部的第一件事还是最后一件事?

它对程序本身有什么不同?

首先,docs don't say that you need to call super. Contrast that to e.g. viewWillAppear(_:), whose docs 状态:

If you override this method, you must call super at some point in your implementation.

因此,仅当您有 UIViewController 的自定义子类时才需要调用 super,我们称它为 BaseViewController,它在 viewDidLoad() 中执行某些操作。

当您从 BaseViewController 继承时,您可能需要调用 super 来完成 BaseViewController 的工作。根据它的性质,您需要在子类 viewDidLoad() 的开头、中间某处或末尾执行此操作。这取决于此 BaseViewController 以正确记录它。

这是一个人为的例子:

class ColorfulViewController: UIViewController {
    /// Defines background color of view. Override in subclass.
    var shinyColor: UIColor = .red

    /// Sets the background color. Make sure to call `super` in subclass.
    func viewDidLoad() {
        backgroundColor = shinyColor
    }
}

class PinkViewController: ColorfulViewController {
    override var shinyColor: UIColor = .systemPink

    func viewDidLoad() {
        super.viewDidLoad() // This one doesn't matter where it goes.
        // Additional work.
    }
}

另一个人为的例子,你想在最后调用 super

class CountingViewController: UIViewController {
    var count: Int = 0

    /// Counts the subviews. When subclassing, make sure to call `super` *after*
    /// view is fully configured.
    func viewDidLoad() {
        count = view.subviews.count
    }
}

class FooViewController: CountingViewController {
    override var shinyColor: UIColor = .systemPink

    func viewDidLoad() {
        // Additional work.
        super.viewDidLoad()
    }
}

视情况而定。通常对于 viewDidLoad() 你会把 super 调用放在方法的开头,因为没有理由不这样做。

您必须了解 super 调用的概念才能更好地理解它。
super.someFunction()调用superclass的一个函数。在我们的例子中,您的自定义视图控制器的 class,假设 MyViewControllerUIViewController,这是最初定义 viewDidLoad() 的地方。在这种情况下,您 覆盖 方法,您应该调用 super 调用以确保没有遗漏任何内容。请注意,在 viewDidLoad() 中,从 UIViewController 调用 super 并不是强制性的,尽管建议将其作为防御性调用。通常文档会提到它是必需的还是不需要的。

如果您有另一个自定义视图控制器,假设 MySecondViewControllerMyViewController 子class,并且您想在 viewDidLoad() 之前执行一些操作MyViewController 发生了,你可以把 MySecondViewControllersuper.viewDidLoad() 放在函数的末尾,或者你想要的地方,像这样:

class MyViewController: UIViewController {

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

class MySecondViewController: MyViewController {

    override func viewDidLoad() {
        // Do something else before doSomething() is called by the superclass
        doSomethingElse()
        super.viewDidLoad()
    }
}