[Obj-C笔记] "self = [super init]"的解释与潜藏bug
2012-12-11 17:38
471 查看
[Obj-C笔记] "self = [super init]"的解释与潜藏bug
Objective-C的推荐init方法写法如下:- (id) init { if(self = [super init]) { //为子类增加属性进行初始化 } return self; }
这里涉及了几个问题,
1. [super init]的作用:
面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化。
2. self 为什么要赋值为[super init]:
简单来说是为了防止父类的初始化方法release掉了self指向的空间并重新alloc了一块空间。这时的话,[super init]可能alloc失败,这时就不再执行if中的语句。
3. super作为消息接受者的实质:
super并不是真正的指针,[super message]的实质是由self来接受父类的message。需要注意的是,[super message]中,message方法出现的self为[super message]语境中的self,即子类实例。
潜藏的bug:
假设有父类AObj与子类BObj。
当AObj的init方法如下:
- (id) init { id tmp = self; self = [AObj alloc]; [tmp release]; //other staffs return self; }
BObj的init方法如下:
- (id) init { if(self = [super init]) { //other staffs } return self; }
这时编译能通过,但当BObj的实例使用到BObj扩充的属性时,就会出现一个运行时错误。错误的原因在于AObj的init方法用[AObj alloc]重新获得了一块仅仅适合存放AObj实例的空间。而BObj的init方法以为这是块适合存放BObj的空间。当试图读写BObj的扩充属性时便会产生运行时错误。
因此,当init方法需要重新alloc一块空间时,正确的写法如下:
- (id) init { id tmp = self; self = [[self class] alloc]; [tmp release]; //other staffs return self; }
注意[self class]将获得self指向的实例对应的类实例,本例中便是BObj。这样AObj的任何子类的init方法都能保证安全了。
相关文章推荐
- [Obj-C笔记] "self = [super init]"的解释与潜藏bug
- [Obj-C笔记] "self = [super init]"的解释与潜藏bug
- [Obj-C笔记] "self = [super init]"的解释与潜藏bug
- self = [super init]"的解释与潜藏bug
- self = [super init]的解释与潜藏bug
- OBJ-C self和super关键字学习笔记
- OC笔记10(成员变量默认值,alloc和init)笔记11(对象的初始化与self)12(id类型与super关键字)
- self = [super init] 最终解释
- Objective-C中init函数(self=[super init])实现的相关研究
- Objective-C语言的 if ( self = [super init] )
- iOS 之self = [super init]
- linux内核学习初笔记(3)u-boot执行第二阶段typedef int (init_fnc_t) (void)解释
- 刨根问底:对于 self = [super init] 的思考
- 2015.7.2 对self=[super init]的查找和补充
- self = [super init]理解
- 类、对象、方法、super、self、init方法
- 小糖出品:关于id、self、super的解释
- Objective-C中init函数实现的相关研究 if ((self = [super init]) != nil)
- Objective-C中init函数实现的相关研究 if ((self = [super init]) != nil)
- python Parent.__init()和super(Child, self)的区别