无论编写任何程序,都需要确保能够有效和高效地管理资源。程序内存就是这些资源中的一种。在Objective-C程序中,必须确保所创建的对象,在不再需要它们的时候被销毁。
注意:iOS不提供垃圾回收机制。
一般规则:
只能释放或自动释放自己所拥有的对象
一般以alloc ,new, copy创建的对象都具有所有权,或者如果向一个对象发送了一条retain消息,也会获得该对象的所有权。
此时需要用release进行释放或者调用自动释放池autorelease;自动释放池的调用是系统来完成的。
需要将接收到的对象存储为某个实例变量的属性,您必须保留或复制该对象。
释放实例:
UIView *view 1= [[UIView alloc]init];
Self.view = view1;
[view1 release];
不需要释放的例子:
UIButton*button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
由于调用的类方法没有使用alloc,new,copy等所以它自动释放,不需要手动释放。
调用自动释放池的例子:
-(NSArray *)rearray
{
NSArray *array = [[NSArray alloc]initWithObjects:@”1”,@”2”,nil];
return [array autorelease];
}
这个方法既没有破坏内存规则,又避免了接收值的使用者不知道何时销毁对象的现象。如果直接return array会造成内存泄露,如果先释放在返回的话会返回无效对象([array release];return array;)这也是错误的。当然如果直接调用类方法就可以这样做:
-(NSArray *)rearray
{
NSArray *array = [NSArray arrayWithObjects:@”1”,@”2”,nil];
return array;
}
在 Objective-C 程序中,对象会被创建和销毁。为了确保应用程序不会使用不必要的内存,对象应该在不需要它们的时候被销毁。当然,在需要对象时保证它们不被销毁也很重要。
任何对象都可能拥有一个或多个所有者。只要一个对象至少还拥有一个所有者,它就会继续存在。如果一个对象没有所有者,则运行时系统会自动销毁它。
可以使用retain来获得一个对象的所有权。
保留计数(retainCount)
在调用retain方法后通过引用计数—通常被称为“保留计数”—实现的。每个对象都有一个保留计数。
创建一个对象时,该对象的保留计数为1。
向一个对象发送retain消息时,该对象的保留计数加1。
向一个对象发送release消息时,该对象的保留计数减1。
向一个对象发送autorelease消息时,该对象的保留计数会在将来的某个阶段减1。
如果一个对象的保留计数被减为0,该对象就会被回收.(直接调用dealloc进行释放)。
当显式地查询对象的保留计数是多少。由于添加了保护机制,当保留计数被减为0时,控制台输出仍然为1因此会造成误导。
共享对象的有效性
Cocoa的所有权策略规定,被接收的对象通常应该在整个调用方法的作用域内保持有效。此外,还可以返回从当前作用域接收到的对象,而不必担心它被释放。对象的getter方法返回一个缓存的实例变量或者一个计算值,这对您的应用程序来说无关紧要。重要的是,对象会在您需要它的这段期间保持有效。
这一规则偶尔也有一些例外情况,主要可以总结为以下两类。
当对象从一个基本的集合类中被删除的时候。
heisenObject = [array objectAtIndex:n];
[array removeObjectAtIndex:n];
// heisenObject could now be invalid.
当对象从一个基本的集合类中被删除时,它会收到一条release(不是autorelease)消息。如果该集合是这个被删除对象的唯一所有者,则被删除的对象(例子中的heisenObject)将被立即回收。
当一个“父对象”被回收的时候。
id parent =