一.autorelease(自动释放池)
1、autorelease 的基本用法
(1) 会将对象放到一个自动释放池中
(2) 当自动释放池被销毁时,会对池子里面的所有对象做一次 release 操作(3) 会返回对象本身
(4) 调用完 autorelease 方法后,对象的计数器不变
//写完这行代码,就不用再写【p release】;
Person *p = [[[Person alloc] init] autorelease];
注意的是,还要把它写在释放池中!
@autoreleasepool{//创建
Person *p = [[Person alloc] init] autorelease];
p.age = 19;
}//此处销毁释放池
2、autorelease 的好处
(1) 不用再关心对象释放的时间
(2) 不用再关心什么时候调用 release
3、autorelease 的使用注意
(1) 占用内存较大的对象不要随便使用 autorelease
(2) 占用内存较小的对象使用 autorelease,没有太大影响
4.错误用法:
//alloc 之后调用了 autorelease,又调用 release
@autoreleasepool {
Person *p = [[[Person alloc] init] autorelease];
[p release];
}
//(2) 连续调用多次 autorelease
@autoreleasepool
{
Person *p = [[[[Person alloc] init] autorelease] autorelease];
}
5、自动释放池
(1) 在 iOS 程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)(2) 当一个对象调用 autorelease 方法时,会将这个对象放到栈顶的释放池
6、自动释放池创建方式
(1) iOS 5.0 之前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool release]; // [pool drain];
(2) iOS 5.0 开始
@autoreleasepool {
}
注意:
1.系统自带的方法中,如果不包含 alloc、new、copy,那么这些方法返回的对象都是已经 autorelease 过的
[NSString stringWithFormat:....];
[NSDate date];
2.开发中经常写一些类方法快速创建一个 autorelease 的对象(创建对象的时候不要直接使用类名,用 self)
提供1个类方法来快速的得到1个对象. 规范 a. 这个类方法以类名开头. 如果没有参数就直接是类名 如果有参数就是 类名WithXX: b. 使用类方法得到的对象,要求这个对象就已经被autorelease过了.
+ (instancetype)person {
return [[[self alloc] init] autorelease];
}
开发小知识:
- (void)dealString {
for (int i=0; i<10000; i++) {
NSString *str = [NSString stringWithFormat:@"%d", i];
NSLog(@"%@", str);
}
}
正常来说,我们声明的10000个局部变量str,会在方法执行结束进行释放,也就是循环结束
如果加上@autoreleasepool
- (void)dealString {
for (int i=0; i<10000; i++) {
@autoreleasepool {
NSString *str = [NSString stringWithFormat:@"%d", i];
NSLog(@"%@", str);
}
}
}
但如果加了自动释放池,局部变量出了自动释放池就释放了,所以局部变量是一边创建一边释放的,会避免局部内存高峰。