一、ARC自动引用计数
1、ARC通过在编译期间自动添加合适的realese/retain/autorelease等函数,来确保对象被正确的释放。
2、ARC只能管理OC的对象,不能管理通过malloc申请的内存。
3、ARC模式下不能调用realese/retain/autorelease这些方法。
4、ARC中,未指定初始值的变量都会被初始化为nil。
5、alloc、copy、mutableCopy、new为开头的方法(即方法族)表示调用者对被创建对象拥有所有权,返回的对象必须是可以被retarin的。
init方法族必须被定义为实例方法,它一定哟啊返回instencetype、id、父类或子类的指针,除了init的方法族,其它方法族可以是类方法也可以是实例方法。
命名时不能误用这些关键字,否则可能造成ARC误释放!!!
6、不要在dealloc中释放实例变量(但可以释放资源),也不要调用[super dealloc]ARC下回自动调用。
二、弱引用
2.1 循环引用
@implementation Person{
id _friend;
}
- (void)setFriend:(id) obj{
_friend = obj;
}
Person * p1 = [[Person alloc] init];
Person * p2 = [[Person alloc] init];
[p1 setFriend:p2];
[p2 setFriend:p1];
A拥有B,B拥有A,ARC时这样写就会出现问题,因为你要释放A,先要等待B释放 反过来,你要释放B,又要等待A释放。循环。这就叫循环引用。于是造成内存泄漏
2.2 弱引用
变量默认定义都是强引用,为了解决循环引用的问题,OC引入弱引用概念
弱引用,能够引用对象,不会成为对象的所有者。
__weak Person * p1; // 弱引用
__strong Person * p2; // 强引用,__strong可以省略,默认强引用
2.3 自动nil化弱引用
弱引用会在其指向的实例对象被释放后自动变成nil。即使弱引用指向的对象偶然释放了,弱引用也不会变成野指针。
@implementation Person{
__weak id _friend;
}
- (void)setFriend:(id) obj{
_friend = obj;
}
Person * p1 = [[Person alloc] init];
Person * p2 = [[Person alloc] init];
[p1 setFriend:p2];
[p2 setFriend:p1];
这样写就不会避免了循环引用。因为friend只是弱引用,只引用了对象。
接着再执行一句如下代码:
p1 = nil;
此时p1被释放,弱引用自动变成了nil此时就是:
p1为nill,p1中的friend弱引用自动释放
p2还存在,p2中的friend弱引用由于p1的释放,自动变为nill,不会变成野指针。
所以使用ARC时,应该尽量保证对象之间的关系呈树形结构。而不是环路。
循环引用时可以采用弱引用,或者手动赋值一方为nil,打破循环关系。
OC和C语言一起使用的时候,ARC还有一些注意事项,这里只就提一下
1、C数组保存OC对象,二重指针使用。有时候要用__strong
2、ARC下不可在C中的结构体定义或引用OC对象
网友评论