一 概念
iOS在程序在运行的过程中,会创建很多个释放池,自动释放池以栈的形式存放的(先进后出)。
对象调用autorelease时,会被放入栈顶的自动释放池中。
当自动释放池销毁时,会对池的所有对象发送一次release消息;
所以发送autorelease之后引用计数不会立即-1。
autorelease返回对象本身。
二 实例
// Person.h @interface Person @property(nonatomic, assign) int age; @end
// Person.m #improt <Foundation/Foundation.h> @implementation Person - (void)dealloc() { NSLog(@"Person dealloc"); [super dealloc]; } @end
// main.m #improt <Foundation/Foundation.h> #improt "Person.h" int main() { @autorelease {// 创建了一个自动释放池 Person* person1 = [[[Person alloc] init] autorelease]; person1.age = 25; }// 释放池销毁,这一行之后会打印出:"Person dealloc" // 释放池个数不限 @autorelease { Person* person2 = [[[Person alloc] init] autorelease]; person2.age = 25; // 释放池可以嵌套 @autorelease { Person* person3 = [[[Person alloc] init] autorelease]; person3.age = 25; } } // 另一种创建方式 NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];// 创建了一个自动释放池 Person* person4 = [[[Person alloc] init] autorelease]; person4.age = 25; [pool release];// 释放池销毁 return 0; }
可见释放池有两种创建方式:
方式一
@autorelease{ // 释放池内对象 }
方式二
NSAutoreleasePool* p = [[NSAutoreleasePool alloc] init];// 创建了一个自动释放池 // 释放池内对象 [pool release];
三 优缺点:
1 优点
不用再关心调用是否放在release之前;
不用关心release是否再所有调用之后。
2 缺点:
不能精确控制对象释放时间;
因此,占用内存较小的对象推荐使用autorelease
四 常见错误
1 多次调用autorelease
Person* person2 = [[[Person alloc] init] autorelease]; [person2 autorelease];
或者
Person* person2 = [[[[Person alloc] init] autorelease] autorelease];
2 调用autorelease之后调用release
Person* person2 = [[[Person alloc] init] autorelease]; [person2 release];
五 类方法自动释放优化
// Person.h @interface Person @property(nonatomic, assign) int age; + (id)person; + (id)personWithAge:(int)age; @end
// Person.m #improt <Foundation/Foundation.h> @implementation Person // 快速返回一个自动释放的对象 + (id)person { retur [Person alloc] init] autorelease]; } + (id)personWithAge:(int)age { Person* p = [Person alloc] init] autorelease]; p.age = age retur p; } @end
// main.m #improt <Foundation/Foundation.h> #improt "Person.h" int main() { @autorelease{ Person* p1 = [Person person]; p1.age = 22; Person* p1 = [Person personWithAge:25]; // 类似的系统方法 NSString* str = [NSString stringWithFormat("%d to string",2)]; NSNumber* n = [NSNumber numberWithInt:100]; } retur 0; }
六 类方法的优化
1 问题示例
从新定义一个类Student继承自Person
// Student.h @interface Student:Person @property(nonatomic, assign) int grade; @end
// Student.m #improt <Foundation/Foundation.h> @implementation Student @end
然后按照下面的方法调用
// main.m #improt <Foundation/Foundation.h> #improt "Person.h" int main() { @autorelease{ Student* s = [Student personWithAge:10]; s.grade = 1;// 报错 } retur 0; }
可以看到在s.grade = 1;的地方报错:
[Person setGrade]:unrecognized selector sent to instance...
为什么呢?因为Student的personWithAge是继承自父类Person,返回的是一个Person对象,
而Person对象是没有grade属性的。
2 解决方法
修改父类Person中的类方法,将Person改为self,返回调用类的对象。
+ (id)person { // 改为self后返回调用者的实例 retur [self alloc] init] autorelease]; } + (id)personWithAge:(int)age { Person* p = [self alloc] init] autorelease]; // 设置父类(Person)的age值 p.age = age retur p; }
时间: 2024-10-28 08:18:29