iOS开发疑问:为何重写初始为nil的变量而非直接赋值?
为什么有的变量要override,有的直接赋值就行?
嘿,这个问题问到点子上了!本质是搞懂Swift里存储属性和计算属性的区别,再结合UIKit框架的属性设计逻辑,就能彻底明白啦~
先看你提到的nibName:它是需要重写的计算属性
UIViewController的nibName是一个计算属性——它不是用来存值的容器,而是用来返回逻辑结果的。系统默认的实现大概是这样的:
open var nibName: String? { // 内部逻辑:比如根据控制器类名自动推断nib,没有匹配的话返回nil return nil }
当你在MainViewController里重写它时,你是在替换这个计算属性的getter逻辑——告诉系统“别用默认规则了,就用我指定的这个字符串”。因为这个属性是从父类UIViewController继承来的,所以必须加override关键字,不然编译器会以为你是在子类里新增了一个和父类同名的属性,而不是覆盖它的原有逻辑。
再看rootViewController:只是给存储属性赋值
AppDelegate里的rootViewController是UIWindow的存储属性——它就是专门用来存对象的容器。你写的代码大概是这样:
window?.rootViewController = MainViewController()
这里你根本不是在“重写”某个属性,只是在给一个已经存在的存储属性设置它的存储值。而且AppDelegate本身并没有从父类继承rootViewController这个属性,你是直接访问window对象的属性来赋值,自然不需要override。
一句话总结override在变量场景的用法
只有当你要修改父类已有的属性逻辑时,才需要用override:
- 重写父类的计算属性(修改get/set逻辑);
- 给父类的存储属性添加
willSet/didSet观察者(比如监听父类属性的变化); - 重写父类存储属性的getter/setter(把存储属性改成计算属性的逻辑,这种场景很少见)。
如果只是给自己的属性赋值,或者访问别人的属性设置值,完全不需要override——因为你没有覆盖任何继承来的东西呀!
举个额外的例子,比如给父类存储属性加观察者,这时候就需要override:
class ParentVC: UIViewController { var pageTitle: String = "默认标题" } class ChildVC: ParentVC { override var pageTitle: String { didSet { // 父类的pageTitle改变时,自动更新导航栏标题 navigationItem.title = pageTitle } } }
内容的提问来源于stack exchange,提问作者Laurence Wingo
相关产品推荐
相关产品推荐

