最近打算精度學習下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!