Object C 内存管理
Object C 内存管理
一. 基本概念:
1. iPhone系统中的Objective-C的内存管理机制是比较灵活的,即可以拿来像C/C++一样用,也可以加个AutoreleasePool让它升级为半自动化的内存管理语言;
2. 引用计数是实例对象的内存回收唯一参考
引用计数(retainCount)是Objective-C管理对象引用的唯一依据。调用实例的release方法后,此属性减一,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法.
3. “拥有的概念”
1) 拥有一个对象的使用权,我们称为拥有这个对象;对象的拥有者个数至少为1,对象才得以存在,否则它应该立即销毁;
2) 获得一个对象所有权的方法:当对对象做alloc,copy,和retain操作之后;
4. “引用”d的概念
面向对象领域里有个引用的概念,区别于继承,引用常被用来当做偶合性更小的设计。一个实例拥有另一个实例的时候,我们称它为引用了另一个实例。
比如ClassA类的一个属性对象的Setter方法:
- ( void )setMyArray:(NSMutableArray *)newArray {
if (myArray != newArray) {
[ myArray setMyArray:nil ];// 这里不用release思考为什么,(在实例的dealloc方法中会调用myArray的realse方法)
myArray = [newArray retain];
}
}
5. 引用记数:
每个对象都有一个引用记数(retainCount),对象被创建的时候引用记数为1;
6. 2
二. 内存管理API及使用准则:
1. alloc:为一个新对象分配内存,并且它的引用记数为1;调用alloc方法,你便拥有新对象的所有权;
2. copy:制造一个对象的副本,改副本的retainCount为1,调用者拥有对副本的所有权;
3. retain: 使retainCount+1;并且拥有对象所有权;
4. release:使retainCount-1;
5. autorealse: 未来的某个时刻使retainCount-1;
6. dealloc:不要手动调用,而是在系统retainCount为0时自动调用;
- (void)dealloc{
[name release];
[super dealloc];
}变量的release顺序与初始顺序相反;
三. 内存管理的原则:
以 1 2 3为A类,(retainCount+1);
以 4,5为B类:retainCount-1
1 .对于同一个对象所做的,A与B的调用次数保持一致;
2. 凡是通过alloc,retain,copy等手段获得对象的所有权;必须在不适用的 使用自己调用release或autoRelease释放;
3. 不要释放不属于自己的对象;
4. autorelease只是意味着延迟发送一个release消息;
5. 对于便利构造器和访问器来说,不用进行释放,因为没有获得对象的使用权;
四. 使用小例子:
1.
Person *person1 = [[Person alloc] initWithName:@”张三”];
NSLog(@”name is %@”,person1.name); //假设从这往后,我们一直都不使用person1 了,应该把对象给释放了。
[person1 release];
2.
erson *person2 = [Person alloc]initWithName:@”李四”];
NSString *name = person2.name;NSLog(@”%@”,name); //假设从这以后,我们也不使用person2了。
[person2 release];
//不应该释放name,因为name是我们间接获得的,所以没有它的所有权
3. 由便利构造器产生的对象不应当使用者销毁,而是由便利构造器本身完成。
+(id) personWithName:(NSString *)aName
{
Person *person = [[Person alloc]
initWithName:aName];
return person; }
①错误,因为返回person对象后,类失去了释放这个对象的机会;
②如果在return语句前加上:[person release];也错误,因为对象已经销毁,不能使用;
③:正确做法:return语句前加上:[person autorelease];
(二)使用便利构造器创建的对象,不需要进行释放;
如:
-(void) printHello
{
NSString *str = [NSString
stringWithFormat:@”Hello”];
NSLog(@”%@”,str); }
4. 访问器和设置器:
1)在设置器中,保持对新传入对象的所有权,同时放弃旧对象的所有权。
-(void) setName:(NSString *) aName{ if(name!= aName){
[name release];//有疑问,会不会造成多次释放;
name = [aName retain];//or copy }
}
2) 在访问器中,不需要retain或release.
-(NSString *)name{
return name; }
3) 用访问器获得的对象,使用完毕后不需要释放。
-(void) printName{
NSString *name = person.name;
NSLog(@”%@”,name); }
5. 常见错误:
1) 未使用设置器
-(void) reset{
NSString *newName = [[NSString alloc]
initWithFormat:@”theNew”]; name = newName;
[newName release]; }
2)内存泄露
-(void) reset{
NSString *newName = [[NSString alloc]
initWithFormat:@”theNew”];
[self setName:newName];
}
3) 释放没有所有权的对象
-(void) reset{
NSString *newName = [NSString
stringWithFormat:@”theNew”];
[self setName:newName];
[newName release];
}
补充:软件开发 , C语言 ,