内存泄漏:就是当对象在其超出生命周期后还继续驻于内存的现象。
用__unsafe_unretained 修饰的对象不在ARC内存管理范围内
__autoreleasing
先看以下代码(ARC环境):
id __weak obj1 = obj0;
NSLog(@"%@",[obj1 class]);
与以下代码是相同的
id __weak obj1 = obj0;
id __autoreleasing temp = obj1;
NSLog("%@",[temp class]);
为什么?在ARC环境下,在访问__weak修饰符的变量时,实际上必定要访问注册到autoreleasepool的对象,因为obj1 只有弱引用,在访问变量过程中,有可能该对象已被废弃,所以加上__autoreleasing修饰符后,会放入autoreleasepool,确保在@autoreleasepool块内这个对象都存在。
OC对象和CoreFoundation对象之间可以通过Toll-Free-Bridge来桥接
ARC的实现
__strong修饰符
自己生成并由自己持有对象
{
id __strong obj1 = [[NSObject alloc] init];
}
{
id obj1 = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj1, @selector(init));
[obj1 release];
}
非自己生成但由自己持有的对象,其中省去了放入Autoreleasepool操作,提高效率。
{
id __strong array = [NSArray array];
}
{
id array = objc_msgSend(NSArray, @selector(array));
objc_retainAutoreleasedReturnValued(array);
objc_release(array);
}
__weak修饰符
{
id __weak obj1 = obj;
}
{
id obj1;
obj1 = 1;
objc_storeWeak(&obj1, obj);
objc_storeWeak(&obj1, 0);
}
把storeWeak第二个参数的地址作为key放到Weak表中,value是第一参数用__weak修饰符的变量的地址。当obj销毁的时候,就去Weak表查找key对应的变量地址,从而赋值为nil。
- 从weak表中获取废弃对象的地址为键值的记录
- 将包含在记录中的所有附有__weak修饰符变量的地址,赋值为nil
- 从weak表中删除该记录
- 从引用计数表中删除废弃对象的地址为键值的记录