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

时间:2019-12-22 19:43:40

标签: ios swift swift5 ipados

我正在学习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()作为函数内的第一件事还是最后一件事?

它对程序本身有什么影响?

2 个答案:

答案 0 :(得分:1)

首先,docs不需要说您需要致电super。将此与例如viewWillAppear(_:),其docs状态:

  

如果您重写此方法,则必须在实现的某个时刻调用super

因此,仅当您具有super的自定义子类时才需要调用UIViewController,我们将其称为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()
    }
}

答案 1 :(得分:1)

这取决于。通常对于viewDidLoad(),您应该将超级调用放在该方法的开头,因为确实没有理由不这样做。

您必须了解super调用的概念才能更好地理解它。
super.someFunction()调用超类的函数。在我们的例子中,您的自定义View Controller的类,假设MyViewControllerUIViewController,这是viewDidLoad()最初定义的位置。在这种情况下,您覆盖该方法,则应调用super调用以确保没有任何残留。请注意,在viewDidLoad()中,尽管建议将其作为防御性调用,但从UIViewController调用父级并不是强制性的。通常,文档中提到它是否必需。

如果您有另一个自定义视图控制器,假设MySecondViewControllerMyViewController的子类,并且您想在viewDidLoad()的{​​{1}}发生之前执行一些操作,您可以将MyViewController中的super.viewDidLoad()放置在函数的末尾或所需的位置,例如:

MySecondViewController