要初步理解ARC首先要有內(nèi)存管理的思考方式:
1 自己生成的對象自己所持有
以alloc,copy,new,mutableCopy為名稱開頭的方法名意味著自己生成的對象只有自己持有。
2 非自己生成的對象自己也能持有
不以alloc,copy,new,mutableCopy為方法名的方法生成的對象是非自己生成并持有。
id obj = [NSArray array];//取得非自己生成并持有的對象,取得的對象存在但自己并不持有
[obj retain]; //自己持有對象
其中 非自己生成的對象,且該對象存在,但自己不持有這個特性是使用 autorelease 來實現(xiàn)的。
3 不再需要自己持有的對象時釋放
4 非自己持有的對象不能釋放
以上為內(nèi)存管理的思考方式。
下面來探討alloc/retain/release/dealloc的實現(xiàn)
//alloc 使用struct objc_layout來保存引用計數(shù),并將其寫入對象內(nèi)存頭部
struct objc_layout {
NSUInteger retained;
};
// alloc 開辟
+ (id)liZhiAlloc {
int size = sizeof(struct objc_layout) + 對象的大小;
struct objc_layout *p = (struct objc_layout *)calloc(1, size);
return (__bridge id)(p + 1);
}
//retainCount 獲取引用計數(shù)
- (NSUInteger)liZhiRetainCount{
return ((__bridge struct objc_layout *)self)[-1].retained;
}
//retain 引用計數(shù)加1
- (id)liZhiRetain {
((__bridge struct objc_layout *)self)[-1].retained ++;
return self;
}
//releace 引用計數(shù)減1
- (void)liZhiReleace {
if (((__bridge struct objc_layout *)self)[-1].retained != 0) {
((__bridge struct objc_layout *)self)[-1].retained --;
} else {
[self lizhiDealloc];
}
}
//dealloc 廢棄對象
- (void)liZhiDealloc
{
struct objc_layout *p = & ((__bridge struct objc_layout *)self)[-1];
free(p);
}
通過以上的探討我們可以得出:
1 在oc的對象中存有引用計數(shù);
2 調(diào)用alloc或者retain引用計數(shù)加一;
3 調(diào)用releace引用計數(shù)減一;
4 引用計數(shù)為0時,廢棄對象。