------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
上次学到了内存管理的内部细节及内存管理的用到的技巧,但是也不难发现之前的操作相当麻烦,否则会使的在实际开发过程中往往不能将重心放在应用的开发上,而苹果官方也为此拿出了解决办法,先有autorelease,再到ARC机制。
一、autorelease
一次retain就要在不使用时就要一次release,但有时候会搞乱顺序出现僵尸对象。
1.autorelease的基本用法
1> 会将对象放到一个自动释放池中
2> 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作
3> 会返回对象本身
4> 调用完autorelease方法后,对象的计数器不变
2.autorelease的好处
1> 不用再关心对象释放的时间
2> 不用再关心什么时候调用release
3.autorelease的使用注意
1> 占用内存较大的对象不要随便使用autorelease
2> 占用内存较小的对象使用autorelease,没有太大影响
4.错误写法
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];
}
5.自动释放池
1> 在iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)
2> 当一个对象调用autorelease方法时,会将这个对象放到栈顶的释放池
6.自动释放池的创建方式
1> iOS 5.0前
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool release]; // [pool drain];
2> iOS 5.0 开始
@autoreleasepool
{
}
格式如下:
@autoreleasepool
{// { 开始代表创建了释放池
// autorelease方法会返回对象本身
// 调用完autorelease方法后,对象的计数器不变
// autorelease会将对象放到一个自动释放池中
// 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作
Person *p = [[[Person alloc] init] autorelease];
p.age = 10;
@autoreleasepool
{
// 1
Person *p2 = [[[Person alloc] init] autorelease];
p2.age = 10;
}
Person *p3 = [[[Person alloc] init] autorelease];
} // } 结束代表销毁释放池
二、ARC机
前面自动释放虽然可以避免release放错位置,但是还是会增加编程的负担,因此出现了ARC机制。它是一种编译器特性的机制,在编译的过程中可以添加修改内存
管理所需的命令,可以使开发人员更多的关注应用的开发,而不需要注重太多内存上面的管理。
1. ARC机制
ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,
因为编译器为你处理了一切ARC 是编译器特性,而不是 iOS 运行时特性,它也不是类似于其它语言中的垃圾收集器。因此 ARC 和手动内存管理性能是一样的,有时还能更加快
速,因为编译器还可以执行某些优化。
ARC 的规则非常简单:只要还有一个强指针变量指向对象,对象就会保持在内存中,若只是一个弱指针指向则会立即被内存释放。
2. ARC特点
1> 不允许调用release、retain、retainCount
2> 允许重写dealloc,但是不允许调用[super dealloc]
3> @property的参数
* strong :成员变量是强指针(适用于OC对象类型)
@property (nonatomic, strong) NSString *text;
* weak :成员变量是弱指针(适用于OC对象类型)
* assign : 适用于非OC对象类型
4> 以前的retain改为用strong
指针分2种:
1> 强指针:默认情况下,所有的指针都是强指针 __strong
2> 弱指针:__weak
注意:
ARC机制环境下要注意
1>不能调用release、retain、autorelease、retainCount
2>可以重写dealloc,但是不能调用[superdealloc]
3>@property: 想长期拥有某个对象,应该用strong,其他对象用weak
4>其他基本数据类型依然用assign
5>两端互相引用时,一端用strong、一端用weak
6>错误写法(没有意义的写法)
__weak Person *p = [[Person alloc] init];
两端互相引用时代码如下:
person.h
#import <Foundation/Foundation.h>
@class Dog;
@interface Person : NSObject
@property (nonatomic, strong) Dog *dog;
@end
person.m
#import "Person.h"
@implementation Person
- (void)dealloc
{
NSLog(@"Person--dealloc");
}
@end
dog.h
#import <Foundation/Foundation.h>
@class Person;
@interface Dog : NSObject
@property (nonatomic, weak) Person *person;
@end
dog.m
#import "Dog.h"
@implementation Dog
- (void)dealloc
{
NSLog(@"Dog--dealloc");
}
@end