当前位置:编程学习 > C/C++ >>

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语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,