——- android培训、java培训、ios培训期待与您交流!
什么是ARC
ARC英文名称:Automatic Reference Counting
ARC是一种编译器特性,编译器会在编译代码的时候自动检测哪里需要插入释放内存的代码,自动生成代码。
ARC的判断准则:
只要没有强指针指向对象,就会释放对象
强指针:默认情况下,所有的指针都是强指针 __strong
若指针:__weak
不使用ARC创建两个类方式:
//创建一个Car类
@interface Car:NSObject
@property(nonatomic,assign) int speed;
@end
@implementation Car
@end
//创建一个Person类,拥有一个Car
@interface Person:NSObject
@property(nonatomic,retain)Car *car;
@end
@implementation Person
//重写dealloc方法
-(void)dealloc
{
[_car dealloc];
[super dealloc];
}
@end
int main()
{
//方法1使用@autoreleasepool
@autoreleasepool
{
Car *c=[[[Car alloc] init] autorelease];
Person *p=[[[Person alloc] init] autorelease];
p.car=c;
}
//方法2
Car *c=[[Car alloc] init];
Person *p=[[Person alloc] init];
p.car=c;
[p release];
[c release];
}
使用ARC之后,
1.不允许调用release,retain,retainCount
2.允许重写dealloc,但不允许调用[super dealloc]
3.@property中的参数:
strong:相当于原来的retain,适用与OC对象类型
weak:相当于原来的assign,适用与OC对象类型
assign:适用于非OC对象类型
使用ARC只需要稍加修改代码:
//创建一个Car类
@interface Car:NSObject
@property(nonatomic,assign) int speed;
@end
@implementation Car
@end
//创建一个Person类,拥有一个Car
@interface Person:NSObject
@property(nonatomic,strong)Car *car;
@end
@implementation Person
//重写dealloc方法
@end
int main()
{
//正常书写代码
Car *c=[[Car alloc] init];
Person *p=[[Person alloc] init];
p.car=c;
}
循环引用
ARC也有缺点,当两个类循环调用的时候如果这样声明
@interface Car:NSObject
@property(nonatomic,strong)Person *person;
@end
@interface Person:NSObject
@property(nonatomic,strong)Car *car;
@end
那么最后Person和Car对象依然不会彻底释放,它们的计数器值不为0,因此解决方案:
一端用strong,另一端用weak
@interface Car:NSObject
@property(nonatomic,weak)Person *person;
@end
@interface Person:NSObject
@property(nonatomic,strong)Car *car;
@end
循环引用的解决方案:
1.ARC
一端用strong,另一端用weak
2.非ARC
一端用retain,另一端用assign
总结
1.为什么使用ARC
ARC机制是编译器的一种特性,使用了ARC之后,程序员就不需要关心内存的管理,将心思专注于主要的功能实现上面。减轻了程序员的负担。
2.ARC的注意
1.程序员不需要关心内存的管理
2.程序员不能使用retain、release、retainCount
3.可以重写dealloc方法,不允许调用[super dealloc]
4.虚幻引用对象时,一端使用strong,一端使用weak