设为首页 加入收藏

TOP

Object C 内存管理
2014-11-23 23:29:56 】 浏览:6043
Tags:Object 内存 管理

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];

}

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇如何使用gdb调试C程序 下一篇C/S架构和B/S架构的概念和区别

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目