1.内存管理出现可能出现的问题
1.内存泄露:不再需要的对象没有释放(例如当内存需要销毁的时候,但是依然存在一个强指针指向他,这时就会存在内存泄露)
2.野指针:没有进行初始化的指针
3.悬空指针:一个指针指向一个被销毁的对象
4.僵尸对象:过度释放的对象
以上情况都可能导致系统奔溃
2.内存管理的原则
1.自己生成的对象自己持有(自己持有即强指针指向生成的内存空间)
2.非自己生成的对象自己也能持有
3.不再需要自己持有的对象时释放(释放只是引用计数减一,指向这块内存的强指针数减一,并不代表释放内存空间)
4.非自己持有的对象无法释放
屏幕快照 2017-05-24 14.58.20.png
注:这里的alloc/retain/release/dealloc指的是NSObject中的alloc类方法/retain类方法/release类方法/dealloc类方法
屏幕快照 2017-05-24 15.13.30.png
2.1 自己生成并持有
alloc new copy mutableCopy
/*
*自己生成并持有对象:指向生成并持有对象的指针被赋值给obj
*/
id obj = [[NSObject alloc]init];
id obj1 = [NSObject new];
/*
*copy方法利于基于NSCopying方法约定,由各类实现的copyWithZone:方法生成并持有对象的副本
*copy方法生成不可变的对象,mutableCopy生成可变的对象
*/
2.2 非自己生成的对象自己也可以持有
/*
*取得非自己生成并持有对象,但是自己不持有对象
*/
id obj = [NSMutableArray array];
/*
*持有对象
*/
[obj retain];
2.3 不再需要自己持有的对象时释放
/*
*自己生成并持有对象
*/
id obj = [[NSObject alloc]init];
[obj release];
/*
*释放对象
*指向对象的指针依然被保留在obj中,貌似可以访问,但是对象一经释放绝对不可以访问
*/
2.4 如果不是自己生成的对象并持有的对象不可以使用release释放,但是如果用retain方法变为自己持有之后,就可以用release释放
总结:用alloc/retain/release/dealloc方法生成并持有的对象,或者用retain方法持有的对象一但不在需要,务必使用release释放掉。
3.系统方法仿写
1.使用某个方法生成对象,并将其返回给该方法的调用方(仿alloc)
-(void)allocObject{
id obj = [[NSObject alloc]init];
return obj;
}
2.使用某个方法生成对象,并将其返回给该方法的调用方,但是它不持有对象(仿array)
-(void)object{
id obj = [[NSObject alloc]init];
[obj autorelease];
return obj;
}
注:release立即释放 autorelease对象放在autorelease pool中,超出范围后自己释放。
网友评论