最近打算精度学习下iOS下的多线程和内存管理方面,就阅读了此书,顺便做点笔记,供以后查阅
1. 第一章,自动引用计数
1.1 什么是自动引用计数
1.2 内存管理/引用计数
1.3 ARC规则
项目中使用混编的时候,可以指定ARC编译模式-fobjc-arc
0. 思考方式:
* 自己生产的对象,自己持有
* 非自己生成的对象,自己也能持有
* 自己持有的对象,不再需要的时候要自己释放
* 非自己持有的对象,无法释放(否则程序会崩溃)
- 修饰符
使用修饰符修饰对象后,如果不赋值,对象默认值为nil
- __strong
ARC模式下 默认id类型都是使用的__strong来修饰。
使用strong修饰的实例之间,可以相互赋值。
strong可以实现基本全部内存管理情况,但是不能处理“循环引用”情况
- __strong
@interface Test:NSObject
{
id __strong obj_;
}
- (void)setObject:(id __strong)obj;
@end
@implementation Test
- (id)init
{
self = [super init];
return self;
}
- (void)setObject:(id __strong)obj
{
obj_ = obj;
}
//以下为循环引用
{
id test0 = [[Test alloc]init]; //对象A, test0强引用,持有对象A
id test1 = [[Test alloc]init]; //对象B,test1强引用,持有对象B
[test0 setObject:test1]; //test0的成员变量obj_ 持有对象B
[test1 setObject:test0]; //test1的成员变量obj_ 持有对象A
}
//因为test0变量超出作用域,强引用失效,所以自动释放对象A
//因为test1变量超出作用域,强引用失效,所以自动释放对象B
//此时,持有对象A的强引用变量为对象B的obj_ (引用计数不为0)
//此时,持有对象B的强引用变量为对象A的obj_
//发生内存泄漏!
- __weak
主要用来处理循环引用情况的
当持有某对象的弱引用时,若该对象被废弃,则此弱引用将自动失效,且处于nil被赋值的状态(空弱引用)
id __weak obj1 = nil;
{
id __strong obj0 = [[NSObject alloc]init]; //对象A, obj0强引用,持有对象A
obj1 = obj0; //obj1变量持有对象的弱引用
}
//因为obj0变量超出其作用域,强引用失效
//所以自动释放自己持有的对象
//此时对象无持有者,废弃该对象
//废弃对象的同时,持有该对象弱引用的obj1变量的弱引用失效,nil赋值给obj1
__weak 只能用于iOS5以上 以及 OS X Lion以上的版本
- __unsafe_unretained
iOS4等以下版本无法使用__weak,则使用__unsafe_unretained.
__unsafe_unretained修饰符的变量不属于编译器的内存管理对象。
附有__unsafe_unretained修饰符的变量同附有__weak修饰符的变量一样,因为自己生成并持有的对象不能继续为自己所有,所以生成的对象会立即被释放。
四个修饰符中,除了这个,其他的修饰符都会默认初始化为nil
* __autoreleasing
id *
类型默认为id __autoreleasing *
类型
注意:在strong修饰的静态数组或者字典中,编译器会自己找时机插入释放强引用的代码,但是在可变数组/字典中,必须用户自己来手动把每个对象置为nil!