第37條:理解“塊”這一概念
塊可以實現(xiàn)閉包棒动』橥眩“擴展extension”加入GCC編譯器雹仿。Clang 是開發(fā)Mac OSX及iOS程序所用嘱吗。
塊與函數(shù)類似玄组。只不過是直接定義在另一個函數(shù)里的,符號^后面跟{}里面是塊的實現(xiàn)代碼。
塊其實就是一個值俄讹。塊類型的語法與函數(shù)指針近似哆致。
與int、float或Objective-C對象一樣患膛,也可以把塊賦給變量摊阀,然后像使用其他變量那樣使用它。
返回類型剩瓶,塊名稱驹溃。parameters:參數(shù)名稱
return_type (^block_name)(parameters)
int add = addBlock(2,5);
默認(rèn)枝缔,被塊所捕獲的變量布疙,是不可以在塊里修改的。若改就報錯愿卸。如果聲明變量的時候可以加上_block修飾符灵临,就可以在塊內(nèi)修改。
塊如果所捕獲的遍歷是對象類型就會自動保留它趴荸。塊本身可視為對象儒溉。有引用計數(shù)。當(dāng)最后一個指向塊的引用移走之后发钝。塊就回收了顿涣。
在存放塊對象的內(nèi)存區(qū)域中,首個變量是指向Class對象的指針酝豪,該指針叫做isa涛碑。其余內(nèi)存里含有塊對象正常運轉(zhuǎn)所需的各種信息。
第36條:不要使用retainCount
OC中通過引用計數(shù)來管理內(nèi)存孵淘。對象有計數(shù)器蒲障,當(dāng)對象的計數(shù)變?yōu)?之后,對象就被系統(tǒng)所回收和摧毀了瘫证。
NSObject有retainCount揉阎,之所以沒有用的原因是:它所返回的保留計數(shù)只是某個給定時間點上的值。該方法并未考慮到系統(tǒng)會稍后把自動釋放池清空痛悯。因而不會將后續(xù)的釋放操作從返回值里減去余黎,所以此值不準(zhǔn)。
while ([object retainCount]) {
[object release];
}
retainCount 可能永遠(yuǎn)不返回0载萌,
第35條:用"僵尸對象"調(diào)試內(nèi)存管理問題
僵尸對象是一個調(diào)試功能惧财。運行期系統(tǒng)會把所有已經(jīng)回收的實例轉(zhuǎn)化為特殊的“僵尸對象”巡扇,而不會真正的回收他們。
第34條:合理運用自動釋放池垮衷,可降低應(yīng)用程序的內(nèi)存峰值厅翔。第33條:以弱引用避免保留環(huán)。
第28條:通過協(xié)議提供匿名函數(shù)搀突。用協(xié)議把自己所寫的API之中的實現(xiàn)細(xì)節(jié)隱藏起來刀闷。將返回的對象設(shè)計為遵從此協(xié)議的純id類型。在字典中仰迁,鍵的標(biāo)準(zhǔn)內(nèi)存管理語義是“設(shè)置時拷貝”甸昏,而值的語義則是“設(shè)置時保留”。設(shè)置鍵值對
-
(void)setobject:(id)object forKey:(id<NSCopying>)key. 鍵的那個參數(shù)其類型為id<NSCopying>,作為參數(shù)值的對象徐许。
這樣實現(xiàn)也不好美尸。所以還是遵循上面的規(guī)則冤议。
這個key參數(shù)可以視為匿名對象施蜜。字典不關(guān)心key對象所屬的具體類。
處理數(shù)據(jù)庫連接的程序庫可以用這個思路雌隅。第27條:使用"class-continuation分類"隱藏實現(xiàn)細(xì)節(jié)翻默。
通過“class-continuation分類”向類中新增實例變量。恰起,如果某屬性在主接口中聲明為“只讀”修械,而類的內(nèi)部又要用設(shè)置方法修改此屬性,那么就在“class-continuation分類”中將其擴展為“可讀寫”检盼。
把私有方法的原型聲明在“class-continuation分類”里面肯污。
若想使類所遵循的協(xié)議不為人所知,則可于“class-continuation分類”中聲明吨枉。
第26條:勿在分類中聲明屬性仇箱。
所有屬性都定義在主接口里。分類是擴展類的功能东羹,而非封裝數(shù)據(jù)。不過只讀屬性可以在分類中使用忠烛。獲取方法不訪問數(shù)據(jù)属提,屬性不需要由實例變量來實現(xiàn)。
分類機制通常用于向無源碼的既有類中新增功能师坎。分類中的方法是直接添加在類里面的恕酸,是咋子運行期系統(tǒng)加載分類時完成的。運行期系統(tǒng)會把分類中所實現(xiàn)的每個方法都加入類的方法列表中胯陋,會覆蓋類中的方法蕊温。多次覆蓋以最后一個分類為準(zhǔn)袱箱。以命名空間來區(qū)別各個分類的名稱與其中所定義的方法。
給名稱加上你專用的前綴义矛,給其中的方法名加上你專用的前綴发笔。
第24條:將類的實現(xiàn)代碼分散到便于管理的數(shù)個分類之中。
用“分類”機制凉翻,將類代碼按邏輯劃入幾個分區(qū)中了讨。類的基本要素(屬性與初始化方法等)都聲明在“主實現(xiàn)”里。
第23條:通過委托與數(shù)據(jù)源協(xié)議進(jìn)行對象間通信垃杖。
委托模式:定義一套接口男杈,某對象若想接受另一個對象的委托,則需遵循此接口缩滨。以便成為其委托對象势就,而這“另一個對象”則可以給其委托對象回傳一些信息,也可以在發(fā)送相關(guān)事件時通知委托對象脉漏。
對象把應(yīng)對某個行為的責(zé)任委托給另外一個類苞冯。令某類經(jīng)由該接口獲取其所需的數(shù)據(jù)。
在向類提供數(shù)據(jù):數(shù)據(jù)源模式侧巨。信息從數(shù)據(jù)源流向類舅锄。而在常規(guī)委托模式中,信息則從類流向受委托者司忱。
第22條:理解NSCopying皇忿。
使用對象時經(jīng)常需要拷貝它。OC中通過copy方法完成坦仍。令自己的類支持拷貝鳍烁。就要實現(xiàn)NSCopying協(xié)議。 -
(id)copyWithZone: (NSZone *)zone 內(nèi)存分成不同的“區(qū)”(zone),對象會創(chuàng)建在某個區(qū)里面繁扎,每個程序只有一個區(qū):“默認(rèn)區(qū)”幔荒。
如果對象需要深拷貝梆暮,新增一個專門執(zhí)行深拷貝的方法。
copy方法由NSObject實現(xiàn),該方法只是以“默認(rèn)區(qū)”為參數(shù)來調(diào)用梳玫〉海“copywithzone”。
若想使某個類支持拷貝功能提澎,只需聲明該類遵從NSCopying協(xié)議姚垃。自己寫的對象具有拷貝功能,需事先NSCopying協(xié)議盼忌。如果自定義對象分為可變版本與不可變版本积糯,同時實現(xiàn)NSCopying與NSMutableCopying協(xié)議掂墓。復(fù)制對象時決定采用淺拷貝還是森1拷貝,盡量執(zhí)行淺拷貝絮宁。