------- <a href="http://www.itheima.com" target="blank">Windows Phone 7手机开发</a>、<a href="http://www.itheima.com" target="blank">.Ios培训</a>、期待与您交流! -------
在前面的内存管理博客中,提到过release方法,它是一个对象方法,返回的是空值。autorelease方法也有着release方法有着大体相同的作用。注意@autoreleasepool这是oc中的一个关键字,而autorelease是oc中的对象方法@autoreleasepool后的大括号中声明一个对象时写上,例如Person *p = [[[Person alloc] init] autorelease];意思是讲,把*p指向的Person类型的对象丢到释放池中,释放池相当于内存空间中的一块,在释放池中,当释放池结束后,系统会自动调用所有oc对象的release方法,释放掉oc对象的内存,而不需要开发者进行手动释放。同时,我们在学习内存管理机制时,必须关闭xcode的ARC机制,否则我们无法调用内存管理相关的方法。
代码演示:
main函数:
#import <Foundation/Foundation.h>
#import "Child.h"
#import "Toy.h"
int main()
{
@autoreleasepool // 释放池的声明,也是释放池的开始
{
Child *c = [[[Child alloc] init] autorelease];
Toy *t = [[[Toy alloc] init] autorelease];
t.price = 100;
c.toy = t;
} // 释放池的结束
return 0;
}
Child类的声明与实现:
#import <Foundation/Foundation.h>
#import "Toy.h"
@interface Child : NSObject
@property (nonatomic,retain) Toy *toy;
@end
#import "Child.h"
@implementation Child
- (void)dealloc
{
NSLog(@"调用了Child类型对象的-dealloc方法");
[_toy release];
[super dealloc];
}
@end
Toy类的声明与实现:
#import <Foundation/Foundation.h>
@interface Toy : NSObject
@property (nonatomic,assign) int price;
@end
#import "Toy.h"
@implementation Toy
- (void)dealloc
{
NSLog(@"调用了价格为%d的Toy类型对象的-dealloc方法",[self price]);
[super dealloc];
}
@end
程序执行的结果为:
通过程序显示的结果,可知,上面代码符合苹果的内存管理机制。有alloc就有release或者是autorelease,此处是后者。
小结:
一、 autorelease需要注意的:
1、内存占用较大的对象,一般不建议使用autorelease,因为autorelease并不能精确的释放内存空间,它只会在释放池结束后释放内存空间
2、内存占用小的对象,使用autorelease影响不大
二、 autorelease的好处:
程序员不需要关心对象何时释放,不需要留心release该写在哪儿,或者是否漏掉了release,可以将注意力更多的集中到业务上来。
三、autorelease的基本用法:
1、将需要autorelease的对象扔到释放池中,也就是@autorelease后面的大括号中,然后写上autorelease方法
2、按照上面写法写好autorelease方法后,计数器的值不会改变,计数器的值减1,是在释放池结束的时候进行
3.、autorelease是一个对象方法,返回值是对象本身
4、在ios程序运行过程中,会创建无数个释放池,这些池子都是以栈结构存在的,栈是一种先进后出的数据结构
5、若多个释放池嵌套,则会先释放嵌套与最里面的释放放池,然后依次往外释放
四、常见的autorelease的错误写法:
1、@autoreleasepool { Child *c = [[[[Chlid alloc] init] autorelease] autorelease]; }
这样写,错误在于,释放池结束时,系统会调用两次release方法,导致内存报错
2、@autorelease{ Child *c = [[[Chlid alloc] init] autorelease] ; [c release]; }
这样写,错误在于,已经将*c指向的对象丢到释放池中,释放池结束后,会自动调用release方法,弱用户手动调用release方法,则会出现对象内部计数器多减去1的操作,会出现操作僵死的对象的错误,也就是报野指针错误,访问了一块坏的或者不可访问的内存区域。