以下讨论在 MRC 下。
1,不要在init和dealloc函数中使用accessor
Don’t Use Accessor Methods in Initializer Methods and dealloc
The only places you shouldn’t use accessor methods to set an instance variable are in initializer methods and dealloc. To initialize a counter object with a number object representing zero, you might implement an init method as follows:
refs :https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html
dealloc 实现:
不推荐:
-(void)dealloc {
self.name = nil;
[super dealloc]
}
推荐:
-(void)dealloc {
[_name release];
_name = nil;
[super dealloc]
}
init 实现:
不推荐:
- init {
self = [super init];
if (self) {
self.count = [[NSNumber alloc] initWithInteger:];
}
return self;
}
推荐:
- init {
self = [super init];
if (self) {
_count = [[NSNumber alloc] initWithInteger:];
}
return self;
}
why: 对于init 中使用 self.name 访问器会引发其他副作用,可能会对键-值观察(KVO)的通知,或者你的子类 重载了 name的属性访问器(子类覆盖了父类的实现。
)
假如Custom 实现如下,有一个属性count.
- init {
self = [super init];
if (self) {
self.count = [[NSNumber alloc] initWithInteger:];
}
return self;
}
Custom 的子类是 CustomSub,且实现如下
- init {
self = [super init];
if (self) {
}
return self;
}
同时重写了父类count 属性访问器
-(NSNumber *)count{
//custom....
}
-(void)setCount:(NSNumber *)number{
//custom.....
}
当你在初始化子类
self = [super init]; 它会从NSObject ->Custom->CustomSub 中 调用init 分别初始化当前类得成员,你子类中重写了Custom 属性访问器,那么就会影响Custom 初始化自己的 成员count . 这是从设计模式上来说,子类不应该去影响父类初始化自己的成员。
这样可能导致其他问题。
如果我们中规中矩的 这么写,可能不会出现问题。
那我要想使坏,那...你懂的。
。
so 我们应该在init 或 dealloc 中使用_count 直接访问属性。
则不会出现上述问题。
dealloc 中使用 self.count
----------有可能count的生命周期已经结束,不能再接受消息--------
上面是从其它文章中拷过来的,我没太明白是在什么样的情况下,按理说 对一个nil 对象发送releas 消息不会有问题。
我个人理解: 其实init 、dealloc 中不建议使用 访问器而直接使用_property 根本原因是
子类不应该去影响 父类 初始化 和 释放 自己资源(property)【通过上面可知子类覆盖父类属性访问器的后果】,使用_property 可以有效避免一些未知错误。
参考:http://stackoverflow.com/questions/8056188/should-i-refer-to-self-property-in-the-init-method-with-arc/8056260#8056260
http://fann.im/blog/2012/08/14/dont-use-accessor-methods-in-init-and-dealloc/
2, 为什么 [super dealloc]; 要在最后
-(void)dealloc {
//custom release self source [super dealloc]
}
释放类的内存是在NSObject 里定义的,释放顺序应该是
先释放我本类里的source , 在调用父类中的dealloc .应该本类中可能拥有不止一个父类,沿着继承链
依次释放父类中的资源。
这个过程和init 过程相反,
-(id)init{
self = [super init];
if(self){
//custom init
}
}
注:可以把init过程比作生成一个洋葱,从最核心的NSObject(分配内存、初始化属性。
)
外层逐层初始化自己的东西,直到本类……
dealloc 同理可以比作 卜洋葱。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)