第1章 熟悉Objective-C
第1條:了解Objective-C語言的起源
- Objective-C 為C語言添加了面向對象特性肠阱,是其超集。Objective-C使用動態(tài)綁定的消息結構朴读,也就是說屹徘,在運行時才會檢查對象類型。
接收一條消息后衅金,究竟應執(zhí)行何種代碼噪伊,由運行期環(huán)境而非編譯器決定。 - 理解C語言的核心概念有助于寫好Objective-C程序氮唯。尤其要掌握內存模型與指針鉴吹。
第2條:在類的頭文件中盡量少引入其他頭文件
- 除非有必要,否則不要引入頭文件惩琉。一般來說豆励,應在某個類的頭文件中使用向前聲明來提及別的類別,并在實現(xiàn)文件中引入那些類的頭文件瞒渠。
這樣做可以盡量降低類之間的耦合良蒸。 - 有時無法使用向前聲明(@class,@protocol等技扼,可防止頭文件的循環(huán)引用),比如要聲明某個類遵循一項協(xié)議嫩痰。
這種情況下淮摔,盡量把“該類遵循某協(xié)議”的這條聲明移至”class-continuation分類”中。如果不行的話始赎,就把協(xié)議單獨放在一個頭文件中,然后將其引入仔燕。
第3條:多用字面量語法造垛,少用與之等價的方法
- 應該使用字面量語法來創(chuàng)建字符串、數(shù)值晰搀、數(shù)組五辽、字典。與創(chuàng)建此類對象的常規(guī)方法相比外恕,這么做更加簡明扼要杆逗。
- 應該通過取下標操作來訪問數(shù)組下標或者字典中的鍵所對應的元素(可變數(shù)組和字典也可通過下標來修改)。
- 用字面量語法創(chuàng)建數(shù)組或字典時鳞疲,值中不能有nil罪郊,否則會拋出異常。
第4條:多用類型常量尚洽,少用#define預處理指令
- 不要用預處理指令定義常量悔橄。這樣定義出來的常量不含類型信息,編譯器只是會在編譯前據(jù)此執(zhí)行查找和替換操作腺毫。即時有人重新定義了常量值癣疟,
編譯器也不會產(chǎn)生警告信息,導致常量值不一致潮酒。 - 在實現(xiàn)文件中使用static const來定義“只在編譯單元內可見的常量”睛挚。由于此類常量不在全局符號表中,所以無需為其名稱加前綴急黎。
- 在頭文件中使用extern來聲明全局常量扎狱,并在相關實現(xiàn)文件中定義其值。這種常量要出現(xiàn)在全局符號表中叁熔,所以其名稱應加以區(qū)隔委乌,通常用與之相關的類名做前綴。
第5條:用枚舉表示狀態(tài)荣回、選項遭贸、狀態(tài)碼
- 應該用枚舉來表示狀態(tài)機的狀態(tài)、傳遞給方法的選項以及狀態(tài)碼等值心软,給這些值起個易懂的名字壕吹。
- 如果把傳遞給某個方法的選項表示為枚舉類型著蛙,而多個選項又可同時使用,那么就將各選項值定義為2的冪耳贬,以便通過按位或操作將其組合起來踏堡。
- 用NS_ENUM與NS_OPTIONS宏來定義枚舉類型,并指明其底層數(shù)據(jù)類型咒劲。這樣做可以確保枚舉是用開發(fā)者所選的底層數(shù)據(jù)類型實現(xiàn)出來的顷蟆,而不會采用編譯器所選的類型。
- 在處理枚舉類型的switch語句中不要實現(xiàn)default分支腐魂。這樣的話帐偎,加入新枚舉之后,編譯器就會提示開發(fā)者:switch語句并未處理所有枚舉蛔屹。
第2章 對象削樊、消息、運行期
第6條:理解“屬性”這一概念
- 可以用@property語法來定義對象中所封裝的數(shù)據(jù)
- 通過“特質”來指定存儲數(shù)據(jù)所需的正確語義
- 在設置屬性所對應的實例變量時兔毒,一定要遵從該屬性所聲明的語義
- 開發(fā)iOS程序時應該使用nonatomic屬性漫贞,因為atomic屬性會嚴重影響性能。
第7條:在對象內部盡量直接訪問實例變量
- 在對象內部讀取數(shù)據(jù)時育叁,應該直接通過實例變量來讀迅脐,而寫入數(shù)據(jù)時,則應通過屬性來寫豪嗽。
- 在初始化方法及dealloc方法中仪际,總是應該直接通過實例變量來讀取數(shù)據(jù)。
- 有時會使用惰性初始化技術配置某份數(shù)據(jù)昵骤,這種情況下树碱,需要通過屬性來讀取數(shù)據(jù)。
第8條:理解“對象等同性”這一概念
- 若想檢測對象的等同性变秦,請?zhí)峁癷sEqual:”與hash方法成榜。
- 相同的對象那個必須具有相同的哈希碼,但是兩個哈希碼相同的對象卻未必相同蹦玫。
- 不要盲目地逐個檢測每條屬性赎婚,而是應該依照具體需求來制定檢測方案。
- 編寫hash方法時樱溉,應該使用計算速度快而且哈希碼碰撞幾率低的算法挣输。
第9條:以“類族模式”隱藏實現(xiàn)細節(jié)
- 類族模式可以把實現(xiàn)細節(jié)隱藏在一套簡單的公共接口后面。
- 系統(tǒng)框架中經(jīng)常使用類族福贞。
- 從類族的公共抽象基類中繼承子類時要當心撩嚼,若有開發(fā)文檔,則應首先閱讀。
第10條:在既有類中使用關聯(lián)對象存放自定義數(shù)據(jù)
- 可以通過“關聯(lián)對象”機制來把兩個對象連起來完丽。
- 定義關聯(lián)對象時可指定內存管理語義恋技,用以模仿定義屬性時所采用的“擁有關系”與“非擁有關系”。
- 只有在其他做法不可時才選用關聯(lián)對象逻族,因為這種做法通常會引入難以查找的bug蜻底。
第11條:理解objc_msgSend的作用
- 消息由接收者、選擇子及參數(shù)構成聘鳞。給某對象“發(fā)送消息”也就相當于在該對象上“調用方法”薄辅。
- 發(fā)給某對象的全部消息都要由“動態(tài)消息派發(fā)系統(tǒng)”來處理,該系統(tǒng)會查出對應的方法抠璃,并執(zhí)行其代碼长搀。
第12條:理解消息轉發(fā)機制
- 若對象無法響應某個選擇子,則進入消息轉發(fā)流程鸡典。
- 通過運行期的動態(tài)方法解析功能,我們可以在需要用到某個方法時再將其加入類中枪芒。
- 對象可以把其無法解讀的某些選擇子轉交給其他對象來處理彻况。
- 經(jīng)過上述兩步之后,如果還是沒辦法處理選擇子舅踪,那就啟動完整的消息轉發(fā)機制纽甘。
第13條:用“方法調配技術”調試“黑盒方法”
- 在運行期,可以向類中新增或替換選擇子所對應的方法實現(xiàn)抽碌。
- 使用另一份實現(xiàn)來替換原有的方法實現(xiàn)悍赢,這道工序叫做“方法調配”,開發(fā)者常用此技術向原有實現(xiàn)中添加新功能货徙。
- 一般來說左权,只有調試程序的時候才需要在運行期修改方法實現(xiàn),這種做法不易濫用痴颊。
第14條:理解“類對象”的用意
- 每個實例都有一個指向Class對象的指針赏迟,用以表明其類型,而這些Class對象則構成了類的繼承體系蠢棱。
- 如果對象類型無法在編譯期確定锌杀,那么就應該使用類型信息查詢方法來探知。
- 盡量使用類型信息查詢方法來確定對象類型泻仙,而不要直接比較類對象糕再,因為某些對象可能實現(xiàn)了消息轉發(fā)功能。
第3章 接口與API設計
第15條:用前綴避免命名空間沖突
- 選擇與你的公司玉转、應用程序或二者皆有關聯(lián)之名稱作為類名的前綴突想,并在所有代碼中均使用這一前綴。
- 若自己所開發(fā)的程序中用到了第三方庫,則應為其中的名稱加上前綴蒿柳。
第16條:提供“全能初始化方法”
- 在類中提供一個全能初始化方法饶套,并于文檔里指明。其他初始化方法均應調用此方法垒探。
- 若全能初始化方法與超類不同妓蛮,則需覆寫超類中的對應方法。
- 如果超類的初始化方法不適應于子類圾叼,那么應該覆寫這個超類方法蛤克,并在其中拋出異常。
第17條:實現(xiàn)description方法
- 實現(xiàn)description方法返回一個有意義的字符串夷蚊,用以描述該實例构挤。
- 若想在調試時打印出更詳盡的對象描述信息,則應實現(xiàn)debugDescription方法惕鼓。
第18條: 盡量使用不可變對象
- 盡量創(chuàng)建不可變的對象筋现。
- 若某屬性僅可于對象內部修改,則在“class-continuation分類”中將其由readonly屬性擴展為readwrite屬性箱歧。
- 不要把可變的collection作為屬性公開矾飞,而應提供相關方法,以此修改對象中的可變collection呀邢。
第19條:使用清晰而協(xié)調的命名方式
- 起名時應遵從標準的Objective-C命名規(guī)范洒沦,這樣創(chuàng)建出來的接口更容易為開發(fā)者所理解。
- 方法名要言簡意賅价淌,從左只有讀起來要像個日常用語中的句子才好申眼。
- 方法名里不要使用縮略后的類型名稱。
- 給方法起名時的第一要務就是確保其風格與你自己的代碼或所要集成的框架相符蝉衣。
第20條:為私有方法名加前綴
- 給私有方法的名稱加上前綴括尸,這樣可以很容易地將其同公共方法區(qū)分開。
2.不要單用一個下劃線做私有方法的前綴病毡,因為這種做法是預留給蘋果公司用的姻氨。
第21條:理解Objective-C錯誤類型
- 只有發(fā)生了可使整個應用程序崩潰的嚴重錯誤時,才應使用異常剪验。
- 在錯誤不那么嚴重的情況下肴焊,可以指派“委托方法”來處理錯誤,也可以吧錯誤信息放在NSError對象里功戚,經(jīng)由“輸出參數(shù)” 返回給調用者娶眷。
第22條:理解NSCopying協(xié)議
- 若想令自己所寫的對象具有拷貝功能,則需實現(xiàn)NSCopying協(xié)議啸臀。
- 如果自定義的對象分為可變版本與不可變版本届宠,那么就要同時實現(xiàn)NSCopying與NSMutableCopying協(xié)議烁落。
- 復制對象時需決定采用淺拷貝還是深拷貝,一般情況下應該盡量執(zhí)行淺拷貝豌注。
- 如果你所寫的對象需要深拷貝伤塌,那么可考慮新增一個專門執(zhí)行深拷貝的方法。
第4章 協(xié)議與分類
第23條:通過委托與數(shù)據(jù)源洗衣進行對象間通信
- 委托模式為對象提供了一套接口轧铁,使其可由此將相關事件告知其他對象每聪。
- 將委托對象應該支持的接口定義成協(xié)議,在協(xié)議中把可能需要處理的事件定義成方法齿风。
- 當某對象需要從另外一個對象中獲取數(shù)據(jù)時药薯,可以使用委托模式。這種情境下救斑,該模式亦稱“數(shù)據(jù)源協(xié)議”
- 若有必要童本,可實現(xiàn)含有位段的結構體,將委托對象是否能響應相關協(xié)議方法這一信息緩存至其中脸候。
第24條:將類的實現(xiàn)代碼分散到便于管理的數(shù)個分類之中
- 使用分類機制把類的實現(xiàn)代碼劃分為易于管理的小塊
- 將應該視為“私有”的方法名叫Private的分類中穷娱,以隱藏實現(xiàn)細節(jié)。
第25條:總是為第三方類的分類名稱加前綴
- 向第三方類中添加分類時运沦,總應給其名稱加上你專用的前綴泵额。
- 向第三方類中添加分類是,總應給其中的方法名加上你專用的前綴茶袒。
第26條:勿在分類中聲明屬性
- 把封裝數(shù)據(jù)所用的全部屬性都定義在主接口里。
- 在“class-continuation分類”之外的其他分類中凉馆,可以定義存取方法薪寓,但盡量不要定義屬性。
第27條:使用“class-continuation分類”隱藏實現(xiàn)細節(jié)
- 通過“class-continuation分類”向類中新增實例變量
- 如果某屬性在主接口中聲明為“只讀”澜共,而類的內部又要用設置方法修改此屬性向叉,那么就在分類中將其擴展為“可讀寫”
- 把私有方法的原型聲明在分類里面。
- 若想使類所遵循的協(xié)議不為人知嗦董,則可于分類中聲明母谎。
第28條:通過協(xié)議提供匿名對象
- 協(xié)議可在某種程度上提供匿名類型。具體的對象類型可以淡化成遵從某協(xié)議的id類型京革,協(xié)議里規(guī)定了對象所應實現(xiàn)的方法奇唤。
- 使用匿名對象來隱藏類型名稱(或類名)。
- 如果具體類型不重要匹摇,重要的是對象能夠響應(定義在協(xié)議里的)特定方法咬扇,那么可以使用匿名對象來表示。
第5章 內存管理
第29條:理解引用計數(shù)
- 引用計數(shù)機制通過可以遞增遞減的計數(shù)器來管理內存廊勃。對象創(chuàng)建好之后懈贺,其保留計數(shù)至少為1。若保留計數(shù)為正,則對象繼續(xù)存活梭灿。若保留計數(shù)降為0時画侣,
對象就被銷毀了。 - 在對象生命期中堡妒,其余對象通過引用來保留或釋放此對象配乱。保留與釋放操作分別會遞增及遞減保留計數(shù)。
第30條:以ARC簡化引用計數(shù)
- 有ARC之后涕蚤,程序員就無須擔心內存管理的問題了宪卿。使用ARC來編程,可省去類中許多“樣板代碼”万栅。
- ARC管理對象生命周期的辦法基本上就是:在合適的地方插入“保留”及“釋放”操作佑钾。在ARC環(huán)境下,變量的內存管理語義可以通過修飾符指明烦粒,
而原來則需要手工執(zhí)行“保留”及“釋放”操作休溶。 - 由方法所返回的對象,其內存管理語義總是通過方法名來體現(xiàn)扰她。ARC將此確定為開發(fā)者必須遵守的規(guī)則兽掰。
- ARC只負責管理Objective-C對象的內存。尤其要注意:CoreFoundation對象不歸ARC管理徒役,開發(fā)者必須適時調用CFRetain/CFRelease孽尽。
第31條:在dealloc方法中只釋放引用并解除監(jiān)聽
- 在dealloc方法里,應該做的事情就是釋放指向其他對象的引用忧勿,并取消原來訂閱的“鍵值觀測(KVO)”或NSNotificationCenter等通知杉女,不要做其他事情。
- 如果對象持有文件描述符等系統(tǒng)資源鸳吸,那么應該專門編寫一個方法來釋放此種資源熏挎。
- 執(zhí)行異步任務的方法不應在dealloc里調用,只能在正常狀態(tài)下執(zhí)行的那些方法也不應再dealloc里調用晌砾,因為此時對象已處于正在回收的狀態(tài)了坎拐。
第32條:編寫“異常安全代碼”時留意內存管理問題
- 捕獲異常時,一定要注意將try塊內所創(chuàng)立的對象清理干凈养匈。
- 在默認情況下哼勇,ARC不生成安全處理異常所需的清理代碼。開啟編譯器標識后呕乎,可生成這種代碼猴蹂,不過會導致應用程序變大,而且會降低運行效率楣嘁。
第33條:以弱引用避免保留環(huán)
- 將某些引用設為weak磅轻,可避免出現(xiàn)“保留環(huán)”珍逸。
- weak引用可以自動清空,也可以不自動清空聋溜。自動清空(autonilling)是隨著ARC而引入新的特性谆膳,由運行期系統(tǒng)來實現(xiàn)。在具備自動清空功能的弱引用上撮躁,
可以隨意讀取其數(shù)據(jù)漱病,因為這種引用不會指向已經(jīng)回收過的對象。
第34條:以“自動釋放池塊”降低內存峰值
- 自動釋放池排布在棧中把曼,對象收到autorelease消息后杨帽,系統(tǒng)將其放入最頂端的池里。
- 合理運用自動釋放池嗤军,可降低應用程序的內存峰值注盈。
- @autoreleasepool這種新式寫法能創(chuàng)建出更為輕便的自動釋放池。
第35條:用“僵尸對象”調試內存管理問題
- 系統(tǒng)在回收對象時叙赚,可以不將其真的回收老客,而是把它轉化為僵尸對象。通過環(huán)境變量NSZombieEnabled可開啟此功能震叮。
- 系統(tǒng)會修改對象的isa指針胧砰,令其指向特殊的僵尸類,從而使該對象變?yōu)榻┦瑢ο笪辍=┦惸軌蝽憫械倪x擇子尖昏,響應方式為:打印一條包含消息內容及其
接受者的消息焊刹,然后終止應用程序狐史。
第36條:不要使用retainCount
- 對象的保留計數(shù)看似有用评凝,實則不然,因為任何給定時間點上的“絕對保留計數(shù)”都無法反映對象生命期的全貌外邓。
- 引入ARC之后撤蚊,retainCount方法就正式廢止了古掏,在ARC下調用該方法會導致編譯器報錯损话。
第6章 塊與大中樞派發(fā)
第37條:理解“塊”這一概念
- 塊是C、C++槽唾、Objective-C中的詞法閉包丧枪。
- 塊可接受參數(shù),也可返回值庞萍。
- 塊可以分配在棧和堆上拧烦,也可以是全局的。分配在棧上的塊可拷貝到堆里钝计,這樣的話恋博,就和標準的Objective-C對象一樣了齐佳,具備引用計數(shù)了。
第38條:為常用的塊類型創(chuàng)建typedef
- 以typedef重新定義塊類型债沮,可令塊變量用起來更加簡單炼吴。
- 定義新類型時應遵從現(xiàn)有的命名習慣,勿使其名稱與別的類型相沖突疫衩。
- 不妨為同一個塊簽名定義多個類型別名硅蹦。如果要重構代碼使用了塊類型的某個別名,那么只需修改相應typedef中的塊簽名即可闷煤。
第39條:用handler塊降低代碼分散程度
- 在創(chuàng)建對象時童芹,可以使用內聯(lián)的handler塊將相關業(yè)務邏輯一并聲明。
- 在有多個實例需要監(jiān)控時鲤拿,如果采用委托模式假褪,那么經(jīng)常需要根據(jù)傳入的對象來切換,而若改用handler塊來實現(xiàn)皆愉,則可直接將塊與相關對象放在一起嗜价。
- 設計API時如果用到了handler塊,那么可以增加一個參數(shù)幕庐,使調用者可通過此參數(shù)來決定應該把塊安排在哪個隊列上執(zhí)行久锥。
第40條:用塊引用其所屬對象時不要出現(xiàn)保留環(huán)
- 如果塊捕獲的對象直接或間接地保留了塊本身,那么就得當心保留環(huán)的問題异剥。
- 一定要找個適當?shù)臅r機解除保留環(huán)瑟由,而不能把責任推給API的使用者。
第41條:多用派發(fā)隊列冤寿,少用同步鎖
- 派發(fā)隊列可用來表述同步語義歹苦,這種做法要比使用@synchronized塊或NSLock對象更簡單。
- 將同步與異步派發(fā)結合起來督怜,可以實現(xiàn)與普通枷鎖機制一樣的同步行為殴瘦,而這么做卻不會阻塞執(zhí)行異步派發(fā)的線程。
- 使用同步隊列及柵欄塊号杠,可以令同步行為更加高效蚪腋。
第42條:多用GCD,少用performSelector系列方法
- performSelector系列方法在內存管理方面容易有疏失姨蟋。它無法確定將要執(zhí)行的選擇子具體是什么屉凯,因而ARC編譯器也就無法插入適當?shù)膬却婀芾矸椒ā?/li>
- performSelector系列方法所能處理的選擇子太過局限了,選擇子的返回值類型及發(fā)送給方法的參數(shù)個數(shù)都受到限制眼溶。
- 如果想把任務放在另一個線程上執(zhí)行悠砚,那么最好不要用performSelector系列方法,而是應該把任務封裝到塊里堂飞,然后調用大中樞派發(fā)機制的相關方法實現(xiàn)灌旧。
第43條:掌握GCD及操作隊列的使用時機
- 在解決多線程與任務管理問題時绑咱,派發(fā)隊列并非唯一方案。
- 操作隊列提供了一套高層的Objective-C API枢泰,能實現(xiàn)純GCD所具備的絕大部分功能羡玛,而且還能完成一些更為復雜的操作,那些操作若改用GCD來實現(xiàn)宗苍,
則需另外編寫代碼稼稿。
第44條:通過Dispatch Group機制,根據(jù)系統(tǒng)資源狀況來執(zhí)行任務
- 一系列任務可歸入一個dispatch group之中讳窟。開發(fā)者可以再這組任務執(zhí)行完畢時獲得通知让歼。
- 通過dispatch group,可以在并發(fā)式派發(fā)隊列里同時執(zhí)行多項任務丽啡。此時GCD會根據(jù)系統(tǒng)資源狀況來調度谋右。開發(fā)者若自己來實現(xiàn)此功能,則需編寫大量代碼补箍。
第45條:使用dispatch_once來執(zhí)行只需運行一次的線程安全代碼
- 經(jīng)常需要編寫“只需執(zhí)行一次的線程安全代碼”改执。通過GCD所提供的dispatch_once函數(shù),很容易就能實現(xiàn)此功能坑雅。
- 標記應該聲明在static或global作用域中辈挂,這樣的話,在把只需執(zhí)行一次的塊傳給dispatch_once函數(shù)時裹粤,傳進去的標記也是相同的终蒂。
第46條:不要使用dispatch_get_current_queue
- dispatch_get_current_queue函數(shù)的行為常常與開發(fā)者所預期的不同,此函數(shù)已經(jīng)廢棄遥诉,只應做調試之用拇泣。
- 由于派發(fā)隊列是按層級來組織的,所以無法單用某個隊列對象來描述“當前隊列”這一概念矮锈。
- dispatch_get_current_queue函數(shù)用于解決不可重入的代碼所引發(fā)的死鎖霉翔,然而能用此函數(shù)解決問題,通常也能改用“隊列特定數(shù)據(jù)”來解決苞笨。
第7章 系統(tǒng)框架
第47條:熟悉系統(tǒng)框架
- 許多系統(tǒng)框架都可以直接使用债朵。其中最重要的是Foundation與CoreFoundation, 這兩個框架提供了構建應用程序所需的許多核心功能猫缭。
- 很多常見任務都能用框架來做葱弟,例如音頻與視頻處理壹店、網(wǎng)絡通信猜丹、數(shù)據(jù)管理等。
- 請記坠杪:用純C寫成的框架與用Objective-C寫成的一樣重要射窒,若想成為優(yōu)秀的Objective-C開發(fā)者藏杖,應該掌握C語言的核心概念。
第48條:多用枚舉脉顿,少用for循環(huán)
- 便利collection有四種方式蝌麸。最基本的辦法是for循環(huán),其次是NSEnumerator遍歷法及快速遍歷法艾疟,最新来吩、最先進的方式則是“塊枚舉法”。
- “塊枚舉法”本身就能通過GCD來并發(fā)執(zhí)行遍歷操作蔽莱,無須另行編寫代碼弟疆。而采用其他便利方式則無法輕易實現(xiàn)這一點。
- 若提前知道待遍歷的collection含有何種對象盗冷,則應修改塊簽名怠苔,指出對象的具體類型。
第49條:對自定義其內存管理語義的collection使用無縫橋接
- 通過無縫橋接技術仪糖,可以在foundation框架中的Objective-C對象與CoreFoundation框架中的C語言數(shù)據(jù)結構之間來回轉換柑司。
- 在CoreFoundation層面創(chuàng)建collection時,可以指定許多回調函數(shù)锅劝,這些函數(shù)表示此collection應如何處理其元素攒驰。然后,可運用無縫橋接技術故爵,將其轉換成具備
特殊內存管理語義的Objective-C collection讼育。
第50條:構建緩存時選用NSCache而非NSDictionary
- 實現(xiàn)緩存時應選用NSCache而非NSDictionary對象。因為NSCache可以提供優(yōu)雅的自動刪減功能稠集,而且是“線程安全的”奶段,此外,它與字典不同剥纷,并不會拷貝鍵痹籍。
- 可以給NSCahe對象設置上限,用以限制緩存中的對象個數(shù)及“總成本”晦鞋,而這些尺度則定義了緩存刪減其中對象的時機蹲缠。但是絕對不要把這些尺度當成可靠的“硬限制”,
它們僅對NSCache其指導作用悠垛。 - 將NSpurgeableData與NSCache搭配使用线定,可實現(xiàn)自動清除數(shù)據(jù)的功能,也就是說确买,當NSPurgeableData對象所占內存為系統(tǒng)所丟棄時斤讥,該對象自身也會從緩存中移除。
- 如果緩存使用得當湾趾,那么應用程序的響應速度就能提高芭商。只有那種“重新計算起來很費事的”數(shù)據(jù)派草,才值得放入緩存,比如那些需要從網(wǎng)絡獲取或從磁盤讀取的數(shù)據(jù)铛楣。
第51條:精簡initialize與load的實現(xiàn)代碼
- 在加載階段近迁,如果類實現(xiàn)了load方法,那么系統(tǒng)就會調用它簸州。分類里也可以定義此方法鉴竭,類的load方法要比分類中的先調用。與其他方法不同岸浑,load方法不參與覆寫機制拓瞪。
- 首次使用某個類之前,系統(tǒng)會向發(fā)送initialize消息助琐。由于此方法遵從普通的覆寫規(guī)則祭埂,所以通常應該在里面判斷當前要初始化的是哪個類。
- load與initialize方法都應該實現(xiàn)得精簡一些兵钮,這有助于保持應用程序的響應能力蛆橡,也能減少引入“依賴環(huán)”的幾率。
- 無法在編譯期設定的全局常量掘譬,可以放在initialize方法里初始化泰演。
第52條:別忘了NSTimer會保留其目標對象
- NSTimer對象會保留其目標,直到計時器本身失效為止葱轩,調用invalidate方法可令計時器失效睦焕,另外,一次性的計時器在觸發(fā)完任務之后也會失效靴拱。
- 反復執(zhí)行任務的計時器垃喊,很容易引入保留環(huán),如果這種計時器的目標對象有保留了計時器本身袜炕,那肯定會導致保留環(huán)本谜。這種環(huán)狀保留關系,可能是直接發(fā)生的偎窘,
也可能是通過對象圖里的其他對象間接發(fā)生的乌助。 - 可以擴充NSTimer的功能,用“塊”來打破保留環(huán)陌知。不過他托,除非NSTimer將來在公共接口里提供此功能,否則創(chuàng)建分類仆葡,將相關實現(xiàn)代碼加入其中赏参。