ARC機(jī)制
以往的OBJC是通過程序員手動(dòng)地管理對象的釋放。ARC(Automatic Reference Counting)自動(dòng)引用計(jì)數(shù),現(xiàn)在是OBJC的默認(rèn)內(nèi)存管理機(jī)制承粤,針對堆上的對象,由編譯器自動(dòng)生成操作引用計(jì)數(shù)的指令(retain,release)來管理對象的釋放穷遂。
管理的對象
受ARC管理 | 不受ARC管理 |
---|---|
OC對象指針 | 值類型(基本類型,struct) |
Block指針 | 其他方式分配的資源(c語言的malloc) |
使用attribute((NSObject))定義的typedef | 非內(nèi)存資源 |
管理的方式
//新創(chuàng)建一個(gè)引用類型的對象娱据,這個(gè)對象的引用計(jì)數(shù)初始為1蚪黑;
NSString *name = [[NSString alloc] initWithString:@"Mono"];
//將對象引用賦值給其它變量或者常量,引用計(jì)數(shù)+1;
NSString *otherName = name;
//或者將將該對象引用賦值給其它對象的屬性或?qū)嵗兞考纱糜?jì)數(shù)+1抒寂;
person.name = name;
//將對象傳入函數(shù)參數(shù),或者返回值掠剑,引用計(jì)數(shù)+1
print(name);//函數(shù)結(jié)束后屈芜,參數(shù)或者局部變量離開函數(shù),該對象的引用計(jì)數(shù)-1朴译;
//將對象加入集合之中井佑,引用計(jì)數(shù)+1;
[array addObject];
//將變量或者常量,或者屬性賦值為nil或者其他值动分,引用計(jì)數(shù)-1;
otherName = nil; or otherName = @"Other Name";
person.name = nil;
//實(shí)例變量和屬性所在的對象唄釋放红选,該對象引用計(jì)數(shù)-1澜公;
[person release];
//將對象從集合中移除的時(shí)候,該對象的引用計(jì)數(shù)-1喇肋;
[array removeObject:name];
//當(dāng)該對象的引用計(jì)數(shù)變?yōu)?的時(shí)候坟乾,內(nèi)存自動(dòng)被釋放。
自動(dòng)釋放池(Autorelease Pool)
如果對象頻繁的進(jìn)行釋放和分配蝶防,那么會(huì)造成瑣碎的內(nèi)存管理負(fù)擔(dān)甚侣。autorelease可以講release的調(diào)用延遲到自動(dòng)釋放池被釋放時(shí)。
當(dāng)自動(dòng)釋放池結(jié)束時(shí)间学,所有接受autorelease消息的對象都將被立即釋放(對象被發(fā)送一條release消息);
AppKit和UIKit框架在處理每一次事件循環(huán)迭代時(shí)殷费,都會(huì)講其放入一個(gè)Autorelease Pool中,大多數(shù)情況無須程序員干預(yù)低葫。
需要手動(dòng)管理Autorelease Pool的情況
1.當(dāng)編寫的程序不是基于UI框架详羡,而是命令行程序時(shí)。
2.如果在循環(huán)中創(chuàng)建大量臨時(shí)對象嘿悬,需要更早地釋放实柠,避免臨時(shí)對象聚集導(dǎo)致內(nèi)存峰值過大。
3.在主線程之外創(chuàng)建新的線程善涨,在新線程開始執(zhí)行處窒盐,需要?jiǎng)?chuàng)建自己的Autorelease Pool。
4.嵌套使用Autorelease Pool的時(shí)候钢拧。
協(xié)議 Protocol
類型的合同約定蟹漓,只描述外部接口,不提供具體的實(shí)現(xiàn)源内。
協(xié)議中無法包含實(shí)例變量牧牢,但可以包含以下的成員:
屬性 (本質(zhì)上是訪問器方法,編譯器不會(huì)合成實(shí)例變量)
實(shí)例方法
類方法
初始化器,析構(gòu)器(不常用)
使用協(xié)議
1.一個(gè)類遵守協(xié)議塔鳍,需實(shí)現(xiàn)該協(xié)議約定的所有@required的成員伯铣,即必須要實(shí)現(xiàn)的成員。
協(xié)議中的屬性必須在實(shí)現(xiàn)類的.h接口文件中聲明(編譯器合成實(shí)例變量)
2.協(xié)議本質(zhì)上是一種類型轮纫,可以作為聲明類型腔寡,但是不能創(chuàng)建實(shí)例。
3.可以使用conformsToProtocl:檢查是否實(shí)現(xiàn)了協(xié)議掌唾。
4.編譯警告:1)未實(shí)現(xiàn)必選方法放前。2)協(xié)議類型變量被賦值為非協(xié)議類型變量。運(yùn)行會(huì)出錯(cuò)糯彬。
協(xié)議的繼承
一個(gè)協(xié)議可以繼承一個(gè)或者多個(gè)協(xié)議凭语。
實(shí)現(xiàn)子協(xié)議的類型,同時(shí)也要實(shí)現(xiàn)父協(xié)議中必須是實(shí)現(xiàn)的成員撩扒。
協(xié)議的組合
一個(gè)類可以同時(shí)實(shí)現(xiàn)多個(gè)協(xié)議似扔,protocal<A,B,C....>來組合多個(gè)協(xié)議
實(shí)現(xiàn)組合協(xié)議的類型,必須實(shí)現(xiàn)組合協(xié)議中的每一個(gè)協(xié)議
協(xié)議中的可選
協(xié)議中使用關(guān)鍵字@optional定義的成員是可以選擇不必實(shí)現(xiàn)的搓谆。
常用的協(xié)議
名稱 | 描述 |
---|---|
NSObject | 包含對象的常用操作炒辉,相等、字符串表示泉手、哈希黔寇。 |
NSCopying | 支持復(fù)制的類型必須遵守該協(xié)議。 |
NSMutableCopying | 在NSCopying協(xié)議的基礎(chǔ)上斩萌,支持復(fù)制數(shù)據(jù)的可變性缝裤。 |
NSFastEnumeration | 實(shí)現(xiàn)快速枚舉for-in的類型采用 |
NSCoding | 支持將對象圖進(jìn)行編碼或解碼以支持對象的序列化 |
類別 Categroy
可增加 | 不可增加 |
---|---|
類方法 | 屬性 |
實(shí)例方法 | 實(shí)例變量 |
重寫父類方法 | 已存在的同名方法 |
在沒有源代碼的情況下,基于某些場合的需要颊郎,為一個(gè)類增加功能倘是。
可增加 | 不可增加 |
---|---|
類方法 | 屬性 |
實(shí)例方法 | 實(shí)例變量 |
重寫父類方法 | 已存在的同名方法 |
命名規(guī)范
文件名:類名+擴(kuò)展方法,如:Person+Sport.h/m
類別的使用
場景
1.適合在沒有源代碼的情況下袭艺,想已經(jīng)封裝的類中添加方法搀崭。
2.為一個(gè)類在某些特殊場景下增加功能。
3.對于復(fù)雜的大型文件分割實(shí)現(xiàn)猾编。
4.可以通過類別重寫現(xiàn)有方法瘤睹,但一般不推薦,這樣會(huì)導(dǎo)致無法調(diào)用被擴(kuò)展的類的初始方法答倡,只能訪問重寫過的方法轰传。
添加類別的對象
1.自己創(chuàng)建的類。
2.系統(tǒng)的類瘪撇。
3.第三方庫获茬。
類別限制
1.類別不能在擴(kuò)展類中添加任何成員變量港庄。
2.重寫現(xiàn)有方法時(shí),無法調(diào)用原始現(xiàn)有對象方法恕曲。
3.若兩個(gè)類別都定義了一個(gè)相同類的相同方法鹏氧,運(yùn)行時(shí)實(shí)際無法確定調(diào)用哪一個(gè)。
擴(kuò)展 Extension
擴(kuò)展支持在編譯時(shí)佩谣,在有類的源代碼的前提下把还,向類添加功能∪准螅可看做是匿名的類別吊履。
接口在.m文件中的@implementation前聲明,實(shí)現(xiàn)代碼在@implementation 內(nèi)實(shí)現(xiàn)调鬓。
擴(kuò)展支持添加以下成員:
1.屬性艇炎。
2.實(shí)例成員。
3.類方法腾窝。
4.實(shí)例方法缀踪。
5.改寫屬性的讀寫屬性。
擴(kuò)展的使用
擴(kuò)展實(shí)現(xiàn)的成員只能在燕锥。m文件內(nèi)部訪問辜贵,類外無法直接往訪問悯蝉。
擴(kuò)展的主要用途在于信息隱藏归形,隱藏一些外部無須訪問、而內(nèi)部實(shí)現(xiàn)又需要使用的屬性鼻由、方法:
1.類的主要接口用于“對類以外公開”
2.類的擴(kuò)展接口用于“對類內(nèi)可見”