You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift deinit方法中使用self是否为最佳实践?与Objective-C是否一致?

在Swift的deinit中使用self是否属于最佳实践?

这个问题特别戳中从Objective-C转Swift开发者的痛点——毕竟老习惯改起来总需要理清楚背后的逻辑,咱们一步步说:

先聊Objective-C里为什么要避免在init/dealloc用self

在Objective-C中,大家会刻意避开在init和dealloc里用self,核心原因有两个:

  • init阶段:对象还没完全初始化完成,如果通过self调用实例方法,万一子类重写了这个方法,子类的实现可能会访问还没初始化的属性,直接引发崩溃;
  • dealloc阶段:对象已经进入销毁流程,isa指针可能被runtime修改,或者一些关联对象已经被释放,此时用self调用方法或访问属性,很容易触发野指针或者意外的行为。

那Swift的deinit里用self到底行不行?

答案是:完全可以,而且很多场景下是必须的最佳实践。

Swift的deinit和Objective-C的dealloc底层逻辑差异很大:

  • Swift的ARC在编译期就做了严格的生命周期管理,deinit被调用时,对象的所有存储属性都还处于可用状态,直到deinit执行完毕,才会开始逐个释放属性;
  • Swift没有Objective-C那种runtime层面的isa指针动态修改(除非你刻意用ObjC runtime API,但那属于特殊场景),self在deinit里的指向是完全确定的。

日常开发中,我们在deinit里做的清理工作几乎都离不开self:

class NotificationSubscriber {
    init() {
        NotificationCenter.default.addObserver(self, selector: #selector(handleNotification), name: .someNotification, object: nil)
    }
    
    @objc private func handleNotification() {}
    
    deinit {
        // 必须用self移除观察者
        NotificationCenter.default.removeObserver(self)
    }
}

再比如取消网络请求、移除KVO观察者、关闭文件句柄这些操作,都需要通过self来访问属性或调用方法,这都是标准的安全写法。

那Swift的init里用self需要注意什么?

顺带提一句,Swift的init确实有约束,但和Objective-C的原因不一样:
Swift要求必须先初始化所有存储属性,才能使用self——这是Swift的安全机制,确保你不会访问未初始化的内存。一旦所有属性都初始化完成,在init里用self调用方法、访问属性都是安全的,不像Objective-C那样有子类重写的隐患(Swift里如果父类的方法是final的,子类根本没法重写;如果是可重写的,你也可以通过super来调用父类实现,避免意外)。

总结

  • Objective-C中init/dealloc避免用self的原则,完全不适用于Swift的deinit;
  • Swift的deinit中使用self不仅安全,还是完成资源清理工作的必要手段,属于最佳实践;
  • Swift的init里用self只要遵守“先初始化所有属性”的规则,就没有问题。

内容的提问来源于stack exchange,提问作者srus2017

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:19:50