前面我们学了OC内存管理的手动引用计数, 一个alloc, 一个release, 对象的释放由我们自己所决定, 在这里应该会有人问, 这样子运用手动引用计数好累, 有没有简单一点的方法, 答案肯定是有的, 现在我们就来看看第一个简单一点的方法, autorelease方法.
首先我们来看看以前所写的例子:
#import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic, assign)int age; @end #import "Person.h" @implementation Person - (void)dealloc { NSLog(@"Person对象被释放了."); [super dealloc]; } @end
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { Person *p = [[Person alloc] init]; p.age = 10; [p release]; return 0; }
打印出来的结果:
2015-01-27 16:39:19.419 08.autorelease基本认识[6599:712028] Person对象被释放了.
这个就是我们之前所写的例子, 在main()函数中, 我们必须得把release写在各种操作之后, 否则就会出现野指针错误, 这个我们在前面就已经知道了, 虽然这样子做可以非常的精准, 但很累人, 所以autorelease出现了, 我们看看修改后的例子:
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [[Person alloc] autorelease]; p.age = 10; } return 0; }
打印出来的结果:
2015-01-27 16:43:29.602 08.autorelease基本认识[6619:713881] Person对象被释放了.
使用了autorelease一样可以让对象被释放~~这样子我们在main()函数里写对象的时候就再去担心对象没有被release.
但注意一下, autorelease的作用并不是释放对象, 只是建造一个自动内存池, 把对象放进去, 只要内存池被销毁, 对象才会被release, 并不是直接释放对象.
还有, autorelease是可以多重嵌套使用的, 比如:
#import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = [[Person alloc] autorelease]; p.age = 10; @autoreleasepool { Person *p1 = [[Person alloc] autorelease]; p1.age = 20; } } return 0; }
打印出来的结果:
2015-01-27 17:19:34.054 08.autorelease基本认识[6672:721475] Person对象被释放了. 2015-01-27 17:19:34.055 08.autorelease基本认识[6672:721475] Person对象被释放了.
注意一点, autorelease使用的场景一般是在占用内存比较小的对象下使用, 比如一个对象里面几乎都是基本数据类型的, 如果是占用内存比较大的对象, 最好还是使用手动引用计数, 否则会引起内存泄漏.
autorelease的错误写法:
1> alloc之后调用了autorelease,又调用release
@autoreleasepool { // 1 Person *p = [[[Person alloc] init] autorelease]; // 0 [p release]; }
2> 连续调用多次autorelease
@autoreleasepool { Person *p = [[[[Person alloc] init] autorelease] autorelease]; }
下面我们来总结一下:
1.autorelease的基本用法
1> 会将对象放到一个自动释放池中
2> 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作
3> 会返回对象本身
4> 调用完autorelease方法后,对象的计数器不变
2.autorelease的好处
1> 不用再关心对象释放的时间
2> 不用再关心什么时候调用release
3.autorelease的使用注意
1> 占用内存较大的对象不要随便使用autorelease
2> 占用内存较小的对象使用autorelease,没有太大影响
4.自动释放池
1> 在iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)
2> 当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池
好了, 这次我们就讲到这里, 下次我们继续~~