重写init方法为什么要self = [super init]

Objective-C中初始化与继承
本文深入探讨了Objective-C中的初始化过程与继承机制,解释了为何需将初始化后的超类赋给self,以及如何避免内存管理错误。同时,文章解析了self指向超类后调用方法的原理,强调了面向对象编程中的重要概念。
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:方秋枋
链接:http://www.zhihu.com/question/22295642/answer/20912142
来源:知乎

这些问题可能Google一下你的收获会更大。
通过你问的问题,可能你还是第一次接触编程语言,或是面向对象语言。你需要了解面向对象的一些概念,相信你认真地把官方文档的 programming with objective-c 研读一遍的话,会有更好的体会。
  • 回答第一个问题:为什么要把初始化好的超类赋给self?

我们需要知道面向对象继承的概念,一个子类从父类继承,获得相关的属性和方法,所以在子类的初始化方法中,必须首先调用父类的初始化方法,以实现父类相关资源的初始化。

网上有网友总结的很好:

1.[super init]的作用:

面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化。

2.self 为什么要赋值为[super init]:

简单来说是为了防止父类的初始化方法release掉了self指向的空间并重新alloc了一块空间。这时的话,[super init]可能alloc失败,这时就不再执行if中的语句。


  • 回答第二个问题:把self指向超类以后,self用点语法调用方法不就直接调用超类的方法了吗?

同样也是面向对象的概念,调用的方法如果是继承自父类的,的确是调用了父类的方法的代码,如果是自己新添加的方法,则调用是原原本本自己的方法。

然后就是在Objective-C发送消息(调用方法)是通过方括号语法来调用的。

 
//

1. 完成自身及父类初始化,保存计数器
2. 要知道,内存中self寻址是按照固定距离去寻址,self= [super init]可以使这个距离保持正确。
3. 安全捕获返回nil的情况

其实内存中还是有很多有意思的地方,比如[Class alloc]和[[Class alloc] init]返回值很可能不同,例如NSString和NSArray这类型的类簇。

转载于:https://www.cnblogs.com/iosdanran/p/5019362.html

你问的是:**类的 `__init__` 方法为什么先执行?** 准确地说,`__init__` 并不是“总是最先执行”的函数。它是在对象创建过程中 **实例初始化阶段自动调用的**,但它前面还有一个关键步骤 —— `__new__` 的执行。 --- ### ✅ 正确理解:`__init__` 的执行时机 当使用 `obj = MyClass()` 创建一个对象时,Python 会按以下顺序执行: 1. 🟩 `__new__`:负责创建对象(分配内存),返回一个实例。 2. 🟨 `__init__`:负责初始化已创建的实例(设置属性等),不返回值。 > 所以:`__init__` 是在 `__new__` **之后**执行的,但在你“能用这个对象之前”最早被执行的方法之一。 --- ### ✅ 示例代码:观察执行顺序 ```python class MyClass: def __new__(cls, *args, **kwargs): print("🔧 __new__ 被调用:创建对象") instance = super().__new__(cls) return instance def __init__(self, name): print("🛠️ __init__ 被调用:初始化对象") self.name = name def show(self): print(f"Hello, {self.name}") # 使用 obj = MyClass("Alice") obj.show() ``` 输出: ``` 🔧 __new__ 被调用:创建对象 🛠️ __init__ 被调用:初始化对象 Hello, Alice ``` > 🔍 可见:`__new__` 先于 `__init__` 执行。 --- ### ❓那为什么说 `__init__` “先执行”? 很多人觉得 `__init__` “最先执行”,是因为: - 大多数情况下我们只写 `__init__`,不重写 `__new__` - `__init__` 是我们编写代码中 **第一个被自动调用的方法** - 我们通常把初始化逻辑放在这里(如赋值、连接数据库、读配置等) 所以从**用户代码视角**来看,`__init__` 是“最早的入口”。 但底层上,它是第二步。 --- ### ✅ 完整流程图解 ```text MyClass() 触发对象创建 ↓ __new__ → 创建实例(分配内存) ↓ 返回实例 __init__ → 初始化实例(设置属性) ↓ 实例可用 ``` --- ### ✅ 特殊情况:如果 `__new__` 没有返回当前类的实例,则不会调用 `__init__` ```python class NoInitCalled: def __new__(cls): print("__new__ 返回了 None,不调用 __init__") return None # 或者返回其他类型的对象 def __init__(self): print("__init__ 不会执行!") obj = NoInitCalled() print(obj) # 输出: None ``` 输出只有: ``` __new__ 返回了 None,不调用 __init__ None ``` > ✅ 结论:只有当 `__new__` 返回的是该类的实例时,Python 才会自动调用 `__init__` --- ### ✅ 常见用途对比 | 方法 | 作用 | 是否需要返回值 | |------|------|----------------| | `__new__` | 创建对象(构造器) | 必须返回实例,否则不调用 `__init__` | | `__init__` | 初始化对象(初始化器) | 不能返回值(或只能返回 `None`) | --- ### ✅ 小结:为什么你觉得 `__init__` “先执行”? - 因为你写的业务逻辑大多从 `__init__` 开始 - 你不常重写 `__new__` - Python 在实例创建后立即调用 `__init__`,中间没有停顿 - 它是你能安全操作实例属性的第一个地方 但从执行顺序看: > `__new__` → `__init__` → 其他方法 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值