一、
自動釋放池的原理
存入到自動釋放池中的對象球榆,在自動釋放池銷毀的時候池摧,會自動調(diào)用儲存在該自動釋放池中的所有對象的release方法.
可以解決的問題:
將創(chuàng)建的對象,存入到自動釋放池之中蕉饼,就不再需要手動的release這個對象了,因為池子銷毀的時候玛歌,就會自動的調(diào)用池中所有的對象release.-
如何創(chuàng)建自動釋放池
@autoreleasepool{}
這對大括號代表這個自動釋放池的范圍 -
如何將對象存儲到這個自動釋放池中
在自動釋放池之中調(diào)用對象的autoreleasepool方法椎椰,就會將這個對象存入到當前自動釋放池之中,這個autorelease方法返回的是對象本身,所以可以這么寫
@autoreleasepool{
Person *p1 = [[[Person alloc] init] autorelease];
}
這個時候沾鳄,當這個自動釋放池執(zhí)行完畢之后慨飘,就會立即為這個自動釋放池中的對象發(fā)送一條release消息.autorelease好處:
創(chuàng)建對象,調(diào)用對象的autorelease方法译荞,將這個對象存入當前的自動釋放池之中瓤的,我們不需要再去release,因為自動釋放池銷毀的時候吞歼,就會自動的調(diào)用池中所有對象的release. 使用注意
1). 只有在自動釋放池中調(diào)用了對象的autorelease方法圈膏,這個對象才會被存儲到這個自動釋放池中,如果只是將創(chuàng)建對象的代碼寫在自動釋放池中,而沒有調(diào)用對象的autorelease方法篙骡,是不會將這個對象存儲到這個自動釋放池之中的.
2). 對象的創(chuàng)建可以在自動釋放池的外面稽坤,在自動釋放池中,調(diào)用對象的autorelease方法糯俗,就可以將這個對象存儲到這個自動釋放池中.
3). 如果對象的autorelease方法的調(diào)用放在自動釋放池的外面尿褪,是無法將其存儲到這個自動釋放池之中的,autorelease的調(diào)用只有放在自動釋放池之中得湘,才可以將其存儲到自動釋放池之中杖玲,對象的創(chuàng)建可以在外面.
4). 當自動釋放池結束的時候,僅僅是對存儲在自動釋放池中的對象發(fā)送一條release消息淘正,而不是銷毀對象.
5). 如果在自動釋放池中摆马,調(diào)用同一個對象的autorelease方法多次,就會將這個對象存儲多次到這個自動釋放池中鸿吆,在自動釋放池結束的時候囤采,就會為對象發(fā)送多次release消息. 所以,一個自動釋放池中惩淳,只autorelease一次蕉毯,只講這個對象放一次,否則就會出現(xiàn)野指針錯誤.
6). 如果在自動釋放池中,調(diào)用了存儲到自動釋放池中的對象的release方法恕刘,在自動釋放池結束的時候缤谎,還會再調(diào)用對象的release方法抒倚,這個時候也有可能會造成野指針操作.
7). 將對象存儲到自動釋放池褐着,并不會使對象的引用計數(shù)器+1,其好處就是創(chuàng)建對象存儲早自動釋放池,就不要再寫release方法了.
8). 自動釋放池可以嵌套.調(diào)用對象的autorelease方法托呕,只會講對象加入到自動釋放池中含蓉,只有在當前自動釋放池結束的時候才會向?qū)ο蟀l(fā)送release消息.-
autorelease規(guī)范
1). 創(chuàng)建對象,將對象存儲到自動釋放池中项郊,就不需要再去手動的release
2). 類方法的第一個規(guī)范:
一般情況下馅扣,要求提供與自定義構造方法相同功能的類方法,這樣可以快速的創(chuàng)建一個對象.
3). 類方法的第二個規(guī)范:
一般情況下着降,會為我們的類寫一個類方法差油,用來讓外界調(diào)用類方法類快速的得到一個對象.
規(guī)范: 使用類方法創(chuàng)建的對象,要求這個對象已經(jīng)被autorelease過了.提供一個類方法來快速的得到一個對象.
規(guī)范:
a. 這個類方法已類名開頭任洞,如果沒有參數(shù)就直接是類名蓄喇,如果有參數(shù)就是withXX:
b. 使用類方法得到的對象,要求這個對象已經(jīng)被autorelease過了+ (instancetype)person{ return [[[selft alloc] init] autorelease]; } 這樣我們直接調(diào)用類方法交掏,就可以得到一個已經(jīng)被autorelease過的對象. @autoreleasepoop{ Person *p1 = [Person person]; // 這個p1對象已經(jīng)被autorelease過了妆偏,不需要再調(diào)用autorelease方法 // 這個對象被存儲到當前的自動釋放池中 }// 當自動釋放池結束,就會為存儲在其中的p1對象發(fā)送release消息.
二盅弛、ARC
-
什么是ARC
Automatic Reference Counting 自動引用計數(shù)钱骂,即ARC
顧名思義: 系統(tǒng)自動的幫助我們?nèi)ビ嬎銓ο蟮膽糜嫈?shù)器的值.在程序中使用ARC非常簡單,只需要像往常一樣編寫代碼.
只不過永遠不要寫retain挪鹏、release见秽、autorelease這三個關鍵字就好,這個ARC最基本的原則.
當ARC開啟時讨盒,編譯器會自動的在合適的地方插入retain张吉、release、autorelease代碼催植,編譯器自動為對象做引用計數(shù)肮蛹,而作為開發(fā)者,完全不需要擔心編譯器會做錯.需要特別注意: ARC是編譯器機制创南,在編譯器編譯代碼的時候伦忠,會在適當?shù)奈恢眉尤雛etain、release稿辙、autorelease代碼.
在ARC機制下昆码,對象何時被釋放: 只要沒有強指針指向這個對象,這個對象就會立即回收.
-
強指針與弱指針
強指針: 默認情況下,我們聲明一個指針赋咽,這個指針就是強指針旧噪,我們也可以使用__strong來顯示的聲明這是一個強指針.Person *p1; 這是一個強指針,指針默認情況下都是一個強指針. __strong Person *p2; 這也是一個強指針脓匿,使用__strong來顯示聲明的強指針.
弱指針: 使用__weak標識的指針就叫做弱指針.
無論強指針還是弱指針淘钟,都是指針,都可以用來存儲地址陪毡,都可以通過這個指針訪問對象的成員米母,唯一的區(qū)別就是在ARC模式下,他們用來作為回收對象的基準.
確認程序是否開啟ARC機制
1). 默認情況下毡琉,Xcode開啟ARC機制
2). ARC機制下铁瞒,不允許調(diào)用retain/release/retainCount/autorelease方法
3). 在dealloc中不允許[super dealloc]-
演示第一個ARC案例
int main(int argc, const char *argv[]){ @autoreleasepool{ Person *p1 = [Person new]; }// 當執(zhí)行到這里,p1指針被回收 return 0; }
-
ARC下的單個對象的內(nèi)存管理
在ARC機制下: 當沒有任何一個強指針指向它的時候桅滋,就會被立即回收.
1). 當指向?qū)ο蟮乃械膹娭羔槺换厥盏臅r候慧耍,對象就會被立即回收int main(int argc, const char *argv[]){ @autoreleasepool{ Person *p1 = [Person new]; Person *p2 = p1; }// 當執(zhí)行到這里,p1指針被回收,p2指針也被回收 return 0; }
2). 將所有指向?qū)ο蟮膹娭羔樫x值為nil的時候丐谋,對象就會被立即回收
int main(int argc, const char *argv[]){ @autoreleasepool{ Person *p1 = [Person new]; p1 = nil; }// 當執(zhí)行到這里芍碧,p1指針被回收,p2指針也被回收 return 0; }
-
強指針與弱指針
1). 強指針與弱指針的聲明
默認情況下,所有的指針都是強類型的.
Person *p1 = [[Person alloc] init];
p1指針是強類型的笋鄙,因為默認情況下指針都是強類型的.
不過我們可以使用__strong來顯示的標識指針是強類型指針.
__strong Person *p2 = [Person new];
這時候p2指針是強類型的师枣,其實寫不寫__strong都是強類型指針.
指針類型也可以是弱指針類型.
使用__weak標識指針的類型是弱類型指針.
__weak Person *p3 = p2;
這時候,p3指針是1個弱類型的指針萧落,p3弱指針也指向p2強指針指向的對象.
在操作對象的時候践美,通過強指針或者弱指針都可以操作,沒有任何區(qū)別2). ARC模式下的對象回收標準
ARC機制下釋放對象的標準找岖,沒有任何強指針指向?qū)ο蟮臅r候陨倡,對象就會被釋放.如果這個時候有弱指針指向,也會被釋放许布。int main(int argc, const char *argv[]){ @autoreleasepool{ __strong Person *p1 = [[Person alloc] init]; __weak Person *p2 = p1; p1 = nil;// 當執(zhí)行到這里兴革,p1指針被回收,p2指針也被回收 } return 0; }
3). 最重要的一點:不能創(chuàng)建對象用1個弱指針存儲這個對象的指針,這樣的話蜜唾,剛創(chuàng)建出來的對象杂曲,就沒有任何強指針指向,創(chuàng)建處理就會被回收.
int main(int argc, const char *argv[]){ @autoreleasepool{ // 創(chuàng)建一個對象袁余,剛創(chuàng)建出來就會被回收 __weak Person *p2 = [[Person alloc] init]; } return 0; }
4). 在ARC的機制下擎勘,原來指向這個對象的弱指針,會被自動設置為nil.
在ARC機制下颖榜,@property參數(shù)就不能使用retain棚饵,因為retain代表生成的setter方法是MRC的標準的內(nèi)存管理代碼煤裙,而我們在ARC機制下不需要那些代碼.
所以在ARC機制下的setter方法,什么都不需要做.ARC機制下噪漾,關注的重點,當一個類的屬性是一個OC對象的時候硼砰,這個屬性應該聲明為強類型的.
1). 控制@property生成的私有屬性,是一個強類型還是弱類型.
使用參數(shù)strong和weak
@property(nonatomic,strong)Car *car;
代表生成的_car是強類型
@property(nonatomic,weak)Car *car;
代表生成的_car是弱類型
如果不寫欣硼,默認是strong使用建議
1). 在ARC機制下题翰,如果屬性的類型是OC對象類型,使用strong
2). 在ARC機制下分别,如果屬性的類型不是OC對象類型遍愿,使用assign
3). strong和weak都是應用在屬性類型是OC對象的時候
4). 在ARC機制下存淫,將MRC下的retain換為strong循環(huán)引用
解決方案: 其中一方使用weak耘斩,另一方使用strong
三、
-
遇到的問題--MRC與ARC兼容
點擊項目->Target->Build Phases->Compile Sources->選中要使用MRC編譯的類桅咆,雙擊->填寫-fno-objc-arc
使用命令-fno-objc-arc
MRC轉換為ARC
Edit-> Convert->To Object-C ARC...->選中要轉成ARC的程序選中括授,點擊Check->Next->Save.-
分類(類別/類目)--category
默認情況一個類獨占一個模塊,這個時候?qū)⑺械某蓡T都寫在這個模塊中岩饼,很難管理荚虚。將功能相似的方法定義在同一個模塊中,這樣的好處籍茧,方便維護和管理版述。
1). 顧名思義: 把類分開,將一個類分為多個模塊
2). 如何為一個類添加分類: Target->New File->Objective-C File->Next,File: itcast File Type: Category Class: Student(選擇要分的類)
Next->Create.
3). 會生成一個.h和一個.m模塊
a. 模塊的文件名是本類名+分類名.h寞冯,本類名+分類名.m
4). 添加的分類分為聲明和實現(xiàn)
@interface 本類名 (分類名)
@end
代表不是新創(chuàng)建一個類渴析,而是對已有的類添加一個分類,小括弧中寫上分類的名字,因為一個類可以添加多個分類,為了區(qū)分每個類
@implementation 本類名 (分類名)
@end
這是分類的實現(xiàn)
5). 分類的使用
a. 如果要訪問分類中定義的成員吮龄,就要把分類的頭文件引進來.6). 分類的作用:就是將一個類分為多個模塊
7). 注意
a. 分類中只能增加方法俭茧,不能增加屬性
b. 在分類中可以寫@property但是不會自動 生成私有屬性,也不會自動生成getter/setter的實現(xiàn)漓帚,只會生成getter/setter的聲明
c. 在分類的方法實現(xiàn)中不可以直接訪問本類的私有屬性母债,但是可以調(diào)用本類的getter/setter來訪問屬性
d. 當分類中有和本類同名方法的時候,優(yōu)先調(diào)用分類的方法尝抖,哪怕沒有引入分類的頭文件毡们,如果多個分類中有多個相同的方法,優(yōu)先調(diào)用最后編譯的分類8). 什么時候需要使用分類
當一個類的方法很多很雜的時候昧辽,比較臃腫的時候衙熔,這個時候就可以使用分類,將功能相似的方法寫在同一個模塊當中 分類的作用在于可以將我們寫的類分為多個模塊
為系統(tǒng)自帶的類寫分類奴迅,這就叫做非正式協(xié)議.
1). 分類的第一個作用: 分為多個模塊青责,方便管理
2). 分類的第二個作用: 為一個已經(jīng)存在的類添加方法