Swift中super前缀的功能解析及新手疑问解答
别担心,完全不用为这个问题致歉——每个Swift新手都会遇到关于super的困惑,这绝对是基础但关键的知识点!让我一步步给你讲清楚。
super? 在Swift中,super是一个关键字,专门用来访问你子类继承自父类的成员——包括方法、属性,甚至初始化器。当你子类重写了父类的某个方法时,super就是你“回到”父类版本方法的桥梁。
super能不能让重写的方法保留父类原有功能? 完全可以!这其实是super最常用的场景之一。
看你提供的代码示例:
override func viewDidLoad() { super.viewDidLoad() // 调用父类的viewDidLoad // 子类自己的逻辑:加载图片 let fm = FileManager.default let path = Bundle.main.resourcePath! let items = try! fm.contentsOfDirectory(atPath: path) for item in items { if item.hasPrefix("nssl") { pictures.append(item) } } }
你的ViewController继承自UITableViewController,而UITableViewController本身的viewDidLoad方法已经包含了很多必要的初始化逻辑:比如设置tableView的默认样式、绑定数据源和代理的默认实现、初始化一些内部组件等等。
如果你去掉super.viewDidLoad()这行,父类的这些初始化工作就不会执行——你的tableView可能会显示异常,甚至根本无法正常工作。而加上这行,就会先让父类完成它该做的事,再执行你子类自己的图片加载逻辑,相当于把父类的原有功能和子类的新功能结合起来。
其实这句话换个说法更好理解:父类的某些方法(尤其是UIKit的生命周期方法,比如viewDidLoad、viewWillAppear)是和系统的组件生命周期绑定的。父类需要在特定时机执行这些方法来维持整个组件的正常运转。
当你在子类重写这些方法时,调用super.方法名()就是在告诉系统:“先让父类完成它在这个生命周期节点该做的事,我再补充自己的逻辑”。这样整个视图控制器的生命周期就会按照系统预期的流程走,不会出现混乱。
比如viewDidLoad是视图控制器加载完成后第一个被调用的方法,父类需要在这里完成基础的初始化,你调用super.viewDidLoad()就是确保这些初始化在你的自定义代码之前执行,顺序完全符合系统要求。
- 不是所有重写都必须调用
super,但UIKit的生命周期方法几乎都需要——官方文档里一般会明确说明,如果没调用可能会触发未知问题。 - 你可以在子类方法的任何位置调用
super(开头、中间、结尾),但大部分UIKit场景下,都是先调用super再写自己的逻辑。 - 除了生命周期方法,如果你自定义了一个父类,子类重写父类的自定义方法时,也可以用
super来复用父类的逻辑。比如父类有个printName()方法,子类重写时可以先调用super.printName()打印父类的内容,再添加自己的自定义打印。
内容的提问来源于stack exchange,提问作者Lio

