1. 主页 > 好文章

iOS子类重写父类方法详解:正确姿势与常见错误

你是不是也遇到过这种情况?明明照着教程写了override关键字,运行的时候突然闪退报错,控制台弹出一堆看不懂的红色警告。这时候是不是特别想问:新手如何快速掌握iOS方法重写的核心要领?今天咱们就来掰扯掰扯这个每个iOS开发者都绕不开的技术点。

先看个真实案例。上周有个学员在群里发代码截图问:"为什么我重写viewDidLoad方法后,页面布局全乱了?"点开代码一看,他居然没写super.viewDidLoad()!这种低级错误其实每天都在发生,特别是对刚接触面向对象编程的小白来说,理解super关键字的重要性比背十遍语法都有用。

??必须记住的三大原则??

  1. override不是装饰品,是必须写的关键字(Swift编译器会强制检查)
  2. 该调super的时候绝对别手软,比如生命周期方法viewDidLoad、viewWillAppear这些
  3. 访问权限要留心,父类用private修饰的方法你想重写也没门

举个活生生的例子。假设咱们要自定义UIButton,想改点击效果。这时候重写touchesBegan方法,正确的姿势应该是:
class CustomButton: UIButton {
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// 这里写你的动画效果代码
}
}

注意看这里有个坑——如果你漏掉super调用,系统原本的点击反馈就没了,用户点了按钮可能连个水波纹效果都看不到。这就像你装修房子把承重墙拆了,表面看着没问题,实际随时可能塌。

??常见错误排行榜??

错误类型典型症状解决办法
忘记super调用页面空白/功能异常Xcode断点看父类方法是否执行
拼错方法名编译报错/方法不执行用CMD+点击查看父类方法声明
权限不足编译直接报错检查父类方法是否为open或public

这时候可能有人要问:什么时候必须调super?什么时候可以不调?这个问题问得好。拿UIViewController的生命周期方法来说,viewDidLoad、viewWillAppear这些必须调super,但像touchesBegan这样的交互方法,父类实现可能只是空方法,这时候调不调super影响不大。

最近帮人review代码时发现个典型问题。有个新手在重写tableView(_:cellForRowAt:)时,把super.tableView(...)写在了最前面,结果导致自定义cell样式被系统默认样式覆盖。这种执行顺序的错误特别隐蔽,有时候甚至要单步调试才能发现。

说到方法重写的实际应用场景,最常见的是这几种情况:

  • 修改控件默认行为(比如禁止UITextField的粘贴功能)
  • 添加埋点统计(在viewWillAppear里插入统计代码)
  • 实现自定义动画效果(重写转场相关方法)

但千万别走极端。上周看到个反例:有人把UIImageView的init方法重写了二十多次,导致项目启动速度慢了三秒。方法重写就像辣椒,适当调味可以,放多了绝对齁死人。

最后说个冷知识。Swift编译器其实比Objective-C严格得多,如果你尝试重写父类没有声明为open或public的方法,Xcode会直接报错不让编译。这种设计虽然让新手觉得烦,但确实能避免很多运行时崩溃的问题。

小编观点:方法重写这个事吧,就像学骑自行车,刚开始总怕摔跤,但掌握平衡点之后就会发现特别简单。关键是多写多试,遇到报错别急着删代码,仔细读错误信息比问人更管用。下次再碰到相关问题,记得先按住CMD键点进父类源码看看,说不定答案就在注释里写着呢。

本文由嘻道妙招独家原创,未经允许,严禁转载