1. 主页 > 好文章

iOS开发必知:子类中调用父类方法的3种场景与代码实现


为什么子类必须调用父类方法?基础原理剖析

当创建UIViewController子类时,你是否疑惑过为什么必须调用super.viewDidLoad()???核心原因在于继承链的完整性??。Objective-C和Swift通过super关键字建立方法调用链,保证父类的内存管理、视图加载等基础功能正常执行。

??典型反例??:

swift复制
override func viewDidLoad() {
    // 遗漏super.viewDidLoad()
    setupUI() // 可能导致视图层级异常
}

这种情况可能引发视图渲染问题,因为父类的视图加载流程被中断。??必须调用super的场景??:

  1. 系统框架明确要求(如NSObject的init方法)
  2. 父类方法包含关键资源分配
  3. 需要维护对象生命周期完整性

场景一:初始化方法中的super调用规范

??疑问??:自定义初始化器时,调用super.init的位置有什么讲究?
??答案??:必须遵循先初始化子类属性,后调用父类初始化的原则。这是因为Swift编译器会检查属性初始值设定是否完成:

swift复制
class CustomView: UIView {
    let margin: CGFloat
    
    // 正确顺序
    override init(frame: CGRect) {
        margin = 20.0
        super.init(frame: frame)
    }
    
    // 错误示范:先调用super.init
    required init?(coder: NSCoder) {
        super.init(coder: coder) // 编译报错
        margin = 20.0
    }
}

??关键要点??:

  • 在Swift中,子类自定义属性必须优先初始化
  • Objective-C需显式调用[super initWith...]
  • 带参数初始化器必须处理参数传递

场景二:重写生命周期方法时的调用时机

??高频问题??:在viewWillAppear中,super应该放在方法开头还是结尾?
??最佳实践??:根据具体框架的文档要求决定。UIKit的典型调用模式:

swift复制
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated) // 必须放在操作父类行为之前
    trackPageView() // 子类扩展功能
}

??对比表格??:

方法类型super调用位置原因说明
视图加载方法方法开头确保父视图树构建完成
数据处理方法方法结尾先处理子类逻辑再传递数据
动画过渡方法方法中部控制动画阶段执行顺序

场景三:自定义方法中super的灵活运用

??开发误区??:所有自定义方法都需要调用super?实际上??只有继承链需要延续时才需要调用??。例如构建可扩展的基类:

swift复制
class BaseNetworkManager {
    func requestData() {
        print("执行基础网络配置") // 需要被子类继承的功能
    }
}

class UserService: BaseNetworkManager {
    override func requestData() {
        super.requestData() // 保留父类核心功能
        print("添加用户鉴权参数") // 子类扩展功能
    }
}

??判断是否调用super的三要素??:

  1. 父类方法是否包含必要实现
  2. 子类是否需要完全覆盖父类行为
  3. 是否在构建模板方法模式

在多年iOS开发实践中,发现90%的super调用问题都源于对框架机制理解不足。特别是在混合开发Swift和Objective-C的项目中,要注意Swift的严格编译检查与Objective-C的动态特性差异。建议建立方法调用流程图,标注必须调用super的节点,这是提升代码健壮性的有效手段。

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