您的位置:首页 > 移动开发 > IOS开发

ios-内存管理 (网上摘抄)

2012-06-13 23:40 127 查看
1.Objective-C中每个对象都对应着他们自己的持有计数(Retain Count),持有计数可以理解为一个整数计数器,当使用alloc方法创建对象的时候,持有计数会自动设置为1。当你向一个对象发送retain消息 时,持有计数数值会增加。相反,当你像一个对象发送release消息时,持有计数数值会减小。当对象的持有计数变为0的时候,对象会释放自己所占用的内 存。

2.调用实例的release方法后,此属性减一,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。 ?????

3.

a,alloc, allocWithZone,new(带初始化)
为对象分配内存,retainCount为“1”,并返回此实例

b,release
retainCount 减“1”,减到“0”时调用此对象的dealloc方法

c,retain
retainCount 加“1”

d,copy,mutableCopy
复制一个实例,retainCount数为“1”,返回此实例。所得到的对象是与其它上下文无关的,独立的对象(干净对象)。

e,autorelease
在当前上下文的AutoreleasePool栈顶的autoreleasePool实例添加此对象,由于它的引入使Objective-C(非GC管理环境)由全手动内存管理上升到半自动化。

参考代码:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

NSObject *o = [[NSObject alloc] init]; //retainCount为1

[o retain]; //retainCount为2

[o release]; //retainCount为1

[o autorelease]; //retainCount为1

[pool release]; //retaincount为0,触发dealloc方法

一篇很容易理解的帖子

出处

/article/4667167.html

对于我们.net开发人员来说,.net为我们提供了自动内存管理的机制,我们不需去关心内存的管理。但是iphone开发中却是不能的。这篇文章将简述一下objective-c的内存管理机制和方法和一些特性。

手动的进行内存管理

Cocoa和Objective-C的类都是NSObject的子类。NSObject中有几个方法进行内存管理。alloc方法为对象分配一片内存空 间。dealloc方法用于释放对象的空间。但是在我们的代码中将永远都不会使用dealloc方法,因为运行时会为你调用此方法释放内存空间。而你需要 做的只是引用计数,稍后介绍什么是引用计数。

除了alloc和dealloc,NSObject的还有retain和release方法两个方法用于引用计数。retain方法给 retainCount变量加1,release方法给retainCount变量减1。当使用alloc为对象分配一片内存空间的时 候,retainCount会为1。在这个对象的生命周期内,这个对象可能继续被其它变量引用。但有新的变量指向这个对象的时候,你应该调用retain 方法,这样运行时才会知道有新的引用指向了这个变量,在这个对象生存期中拥有它的使用权。这个被Objective-C开发人员称之为“拥有”。例如:

Foo * myFooOne = [[Foo alloc] init]; //retaincount 为1
Foo * myFooTwo = myFooOne; //myFooTwo 指向了这个对象
//retaincount 仍然为1
[myFooTwo retain]; //调用retain方法,运行时才知道myFooTwo指向了该对象,retaincount 为2

上面的代码中,myFooTwo通过调用retain方法,取得了Foo对象的拥有权。在这个对象的生命周期中,会有很多变量来指向和引用它。指向这个对
象的变量也可以通过release方法来解除这种拥有权。release方法将会告诉运行时,我已经使用完这个变量了,已经不需要它
了,retainCount计数减1。

当对象的retainCount的计数大于或者等于1的时候,运行时会继续维持这个对象。当对象的retainCount为0的时候,运行时会释放这个对象,并回收它占得内存空间。

下图展示了一个Foo对象的生命周期。Foo对象首先在内存中分配一个内存空间,并且被myFooOne引用。在这个时候Foo对象的retaincount为1。

Foo * myFooOne = [[Foo alloc] init];



第二个引用变量指向Foo对象,这个引用变量接着调用retain方法,其实也是调用Foo对象的retain方法。Foo对象的retaincount变成2。

Foo * myFooTwo = myFooOne;
[myFooTwo retain];

接着当myFooOne引用不需要的时候,通过调用release方法,解除与Foo对象的拥有权,Foo对象的retaincount变成1。

[myFooOne release];

但myFooTwo不在需要的时候,同样通过调用release方法,解除与Foo对象的拥有权,Foo对象的retaincount变成0。

内存泄露

我们经常会在一个方法中声明对象,看下面这个例子:

-(void) myMethod {
//incorrect method
NSString * myString = [[NSString alloc] init]; //retainCount = 1
Foo * myFoo = [[Foo alloc] initWithName:myString]; //retainCount = 1
NSLog(@"Foo's Name:%@", [myFoo getName]);
}

这上面这个方法中,我们为myString
和myFoo分配了内存空间。方法执行结束之后,两个变量超出了作用域的范围,所以不再有效。但是这个方法并没有releases这两个对象。所以运行时
没有释放这两个变量占据的内存空间。除非你的应用程序结束,否则这两个变量占据的内存空间一直都是不可用的。我们把它称之为内存泄露。

为了防止内存泄露。无论什么时候,我们创建一个对象,或者创建一个对象的拷贝,我们都必须通过release方法释放。

-(void) myMethod {
NSString * myString = [[NSString alloc] init]; //retainCount=1
Foo * myFoo = [[Foo alloc] initWithName:myString]; //retainCount=1
NSLog("Foo's Name:%@", [myFoo getName]);
[myFoo release]; //retainCount=0 so deallocate
[myString release]; //retainCount=0 so deallocate
}

弱引用

看下面的例子:

-(void) myMethod {
//an incorrect method
Foo * myFooOne = [[Foo alloc] initWithName:@"James"]; //retainCount=1
Foo * myFooTwo = myFooOne; //retainCount still 1
[myFooOne release]; //retaincount=0 so deallocated
NSLog("Name:%@", [myFooTwo printOutName]); //runtime error
}

nyFooTwo指向了Foo对象,但是没有调用retain方法,就是一种弱引用,上面的代码会在运行时报错。因为myFooOne调用
release方法。retaincount变成0,运行时,回收了对象的内存空间。然后myFooTwo调用printPutName自然就报错了,见
下图说明。



总结:本文简单的介绍了一下手动的进行内存管理、内存泄露、弱引用等objective-c的知识。

作者:朱祁林

出处:http://zhuqil.cnblogs.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: