1、在OC中只有当对一个对象做了alloc,copy和retain等操作之后,才拥有它的所以权;当对象不再需要,我们应该释放对它的所有权,立即销毁。不要对没有所有权的对象进行释放,例如对你间接获得的:
Person *p=[Person alloc] initWithName:@”cc”];
NSString *name=p.name;
[p release];
我们不能释放name,因为它是我们间接获得的。
Cocoa引用计数的机制实现了该逻辑模型。每个对象都有一个引用计数器(retainCount),对象被创建时引用计数器为1;当引用计数器为0的时,对象将被系统销毁。dealloc方法会在对象引用计数器为0时被系统调用。在dealloc方法对变量的释放顺序应与初始化顺序相反,最后调用[super dealloc]。
如果对一个对象使用了alloc,[mutable]copy,retain,那么必须使用相应的release或autorelease。
alloc:为一个新对象分配内存,并且它的引用计数为1,并且获得对新对象的所有权。
copy:制造一个对象的副本,该副本引用计数为1,调用者获得对副本的所有权。
retain:对象引用计数加1,并且获得对象的所有权。
release:对象引用计数减1,并且放弃对象的所有权。
autorelease:也能使对象引用计数减1,只不过是在未来的某个时间是对象的引用计数减1。
问题如下:
student *stud=[[student alloc]init];
[stud print];
NSLog(@"the count is %lu",(unsigned long)[stud retainCount]);//输出1
[stud retain];
NSLog(@"the count is %lu",(unsigned long)[stud retainCount]);//输出2
[stud release];
NSLog(@"the count is %lu",(unsigned long)[stud retainCount]);//输出1
[stud release];
NSLog(@"the count is %lu",(unsigned long)[stud retainCount]);//还是1
在最后release之后,输出的还是1。这是为什么呢?如果我们重写dealloc方法,如下:
-(void)dealloc{
NSLog(@"shifang");
[super dealloc];
}
则它会在最后输出1之前,输出shifang。
回答:引用计数的问题不必纠结,不光你自己alloc或者copy会导致引用计数增加,系统自己也会将之增减,只不过系统增加了多少,它自己会减少多少,你不要 用打印引用计数的方法来查看操作是否正确,举个简单的例子a = [aclass alloc] init] 这时候a的计数是1 [b addsubview a] 这时候a的计数应该是2或者更多 你relese之后 只会减1,至于此时a的计数到底是多少 是不确定的,可以肯定的是,再你操作对a从初始化到最后操作完毕之后,dealloc 之前,a的计数应该是1,否则不能释放
2、便利构造器
由便利构造器产生的对象不应当由使用者销毁,而是由便利构造器本身完成。即使用便利构造器创建对象,则使用完毕后不需要进行释放。
+(id) personWithName:(NSString *) newName
{
Person *p=[[Person alloc]initWithName:newName];
[p autorelease]; //不能用release,这样的话对象已被销毁,不能使用了
return p;
}
3、设置器
@interface student : NSObject<protocalcc>{
NSString *_name;
}
在设置器中,保持对新传入对象的所有权,同时放弃旧对象的所有权。
-(void)setName:(NSString *)newName
{
if(_name!=newName)
{
[_name release];
_name=[newName retain];//或者copy
}
}
在访问器中,不需要retain或release。
-(NSString *)name
{
Return name;
}