<h3>第1章 熟悉Objective-C</h3>
<h4>第1條:了解OC語言的起源</h4>
要點(diǎn):
1.OC為C語言添加了面向?qū)ο筇匦裕瞧涑妹印C使用動態(tài)綁定的消息結(jié)構(gòu),也就是說啥箭,在運(yùn)行時才會檢查對象類型治宣。接收一條消息之后砌滞,究竟應(yīng)執(zhí)行何種代碼贝润,由運(yùn)行期環(huán)境而非編譯器來決定铝宵。
2.理解C語言的核心概念有助于寫好OC程序。尤其要掌握內(nèi)存模型與指針尊蚁。
<h4>第2條:在類的頭文件中盡量少引入其他頭文件</h4>
@class 向前引用
要點(diǎn):
1.除非確有必要侣夷,否則不要引入頭文件百拓。一般來說,應(yīng)在某個類的頭文件中使用向前聲明來提及別的類耐版,并在實(shí)現(xiàn)文件中引入那些類的頭文件粪牲。這樣做可以盡量降低類之間的耦合(coupling)。
2.有時無法使用向前聲明落君,比如要聲明某個類遵循一項協(xié)議亭引。這種情況下,盡量把"該類遵循某協(xié)議"的這條聲明移至"class-continuation分類"中纹冤。如果不行的話购公,就把協(xié)議單獨(dú)放在一個頭文件中,然后將其引入知残。
<h4>第3條:多用字面量語法比庄,少用與之等價的方法</h4>
要點(diǎn):
1.應(yīng)該使用字面量語法來創(chuàng)建字符串、數(shù)值制恍、數(shù)組吧趣、字典。與創(chuàng)建此類對象的常規(guī)方法相比岔霸,這么做更加簡明扼要俯渤。
2.應(yīng)該通過取下標(biāo)操作來訪問數(shù)組下標(biāo)或字典中的鍵所對應(yīng)的元素。
3.用字面量語法創(chuàng)建數(shù)組或字典時絮爷,若值中有nil梨树,則會拋出異常抡四。因此,務(wù)必確保值里不含nil淑履。
<h4>第4條:多用類型常量藻雪,少用#define預(yù)處理指令</h4>
預(yù)處理指令 #define ANIMATION_DURATION 0.3
缺點(diǎn):預(yù)處理過程會把碰到的所有ANIMATION_DURATION一律替換為0.3,這樣的話指煎,假設(shè)此指令聲明在某個頭文件中瑰排,那么所有引入了這個頭文件的代碼暖侨,其ANIMATION_DURATION都會被替換字逗。
若不打算公開某個常量宅广,則應(yīng)將其定義在使用該常量的實(shí)現(xiàn)文件中
static const NSTimeInterval kAnimationDuration = 0.3
優(yōu)點(diǎn):清楚的描述了常量的含義跟狱。由此可知該常量類型為NSTimeInterval户魏,這有助于為其編寫開發(fā)文檔。如果要定義許多常量关翎,那么這種方式能令稍后閱讀代碼的人更容易理解其意圖鸠信。
還要注意常量名稱。常用的命名法是:若常量局限于某“編譯單元”(translation unit爽茴,也就是“實(shí)現(xiàn)文件”绰垂,implementation file)之內(nèi)劲装,則在前面加字母k;若常量在類之外可見琳袄,則通常以類名為前綴纺酸。
有時候需要對外公開某個常量。比方說碎紊,你可能要在類代碼中調(diào)用NSNotificationCenter以通知他人樊诺。用一個對象來派發(fā)通知词爬,令其他欲接收通知的對象向該對象注冊,這樣就能實(shí)現(xiàn)此功能了锅锨。派發(fā)通知時,需要使用字符床來表示此項通知的名稱必指,而這個名字就可以聲明為一個外界的常值變量恕洲。這樣的話,注冊者無需知道實(shí)際字符串值谱邪,只需以常值變量來注冊自己想要接收的通知即可庶诡。應(yīng)該這樣來定義:
// In the header file
extern NSString *const EOCStringConstant;
// In the implementation file
NSString *const EOCStringConstant = @"VALUE";
這個常量在頭文件中“聲明”末誓,且在實(shí)現(xiàn)文件中“定義”。注意const修飾符在常量類型中的位置迅栅。所以在本例中晴玖,EOCStringConstant就是“一個常量呕屎,而這個常量是指針,指向NSString對象”秀睛。這與需求相符:我們不希望有人改變此指針常量,使其指向另一個NSString對象椭迎。
其他類型的常量也是如此田盈。假如要把前例中EOCAnimatedView類里的動畫播放時長對外公布,那么可以這樣聲明:
// EOCAnimatedView.h
extern const NSTimeInterval EOCAnimatedViewAnimationDuration;
// EOCAnimatedView.m
const NSTimeInterval EOCAnimatedViewAnimationDuration = 0.3;
這樣定義常量要優(yōu)于使用#define預(yù)處理指令简软,因?yàn)榫幾g器會確保常量值不變。一旦在EOCAnimatedView.m中定義好语泽,即可隨處使用视卢。而采用預(yù)處理指令所定義的常量可能會無意中遭人修改廊驼,從而導(dǎo)致應(yīng)用程序各個部分所使用的值互不相同妒挎。
總之,勿食用預(yù)處理指令定義常量鳞芙,而應(yīng)該借助編譯器來確保常量正確期虾,比方說可以在實(shí)現(xiàn)文件中用static const 來聲明常量镶苞,也可以聲明一些全局常量。
要點(diǎn):
1.不要用預(yù)處理指令定義常量壕鹉。這樣定義出來的常量不含類型信息聋涨,編譯器只是會在編譯前據(jù)此執(zhí)行查找與替換操作牍白,即使有人重新定義了常量值,編譯器也不會產(chǎn)生警告信息笙各,這將導(dǎo)致應(yīng)用程序中的常量值不一致础芍。
2.在實(shí)現(xiàn)文件中使用static const來定義“只在編譯單元內(nèi)可見的常量”(translation-unit-specific constant)仑性。由于此類常量不在全局符號表中,所以無須為其名稱加前綴歼捐。
3.在頭文件中使用extern來聲明全局常量,并在相關(guān)實(shí)現(xiàn)文件中定義其值贷盲。這種常量要出現(xiàn)在全局符號表中剥扣,所以其名稱應(yīng)加以區(qū)隔钠怯,通常用與之相關(guān)的類名做前綴。
<h4>第5條:用枚舉表示狀態(tài)鞠鲜、選項断国、狀態(tài)碼</h4>
一個字節(jié)含8個二進(jìn)制位并思,所以至多能表示可取256種(2的8次方)枚舉(編號為0~255)的枚舉變量。
要點(diǎn):
1.應(yīng)該用枚舉來表示狀態(tài)機(jī)的狀態(tài)弄砍、傳遞給方法的選項以及狀態(tài)碼等值音婶,給這些值起個易懂的名字莱坎。
2.如果把傳遞給某個方法的選項表示為枚舉類型,而多個選項又可同時使用碴卧,那么就將各選項值定義為2的冪住册,以便通過按位或操作將其組合起來瓮具。
3.用NS_ENUM與NS_OPTIONS宏來定義枚舉類型,并指明其底層數(shù)據(jù)類型叹阔。這樣做可以確保枚舉是用開發(fā)者所選的底層數(shù)據(jù)類型實(shí)現(xiàn)出來的耳幢,而不是采用編譯器所選的類型。
4.在處理枚舉類型的switch語句中不要實(shí)現(xiàn)defauly分支委煤。這樣的話修档,加入新枚舉之后府框,編譯器就會提示開發(fā)者:switch語句并未處理所有枚舉迫靖。
<h3>第2章 對象系宜、消息、運(yùn)行期</h3>
<h4>第6條:理解“屬性”這一概念</h4>
<h4>第7條:在對象內(nèi)部盡量直接訪問實(shí)例變量</h4>
<h4>第8條:理解“對象等同性”這一概念</h4>
<h4>第9條:以“類族模式”隱藏實(shí)現(xiàn)細(xì)節(jié)</h4>
<h4>第10條:在既有類中使用關(guān)聯(lián)對象存放自定義數(shù)據(jù)</h4>
<h4>第11條:理解objc_msgSend的作用</h4>
<h4>第12條:理解消息轉(zhuǎn)發(fā)機(jī)制</h4>
<h4>第13條:用“方法調(diào)配技術(shù)”調(diào)試“黑盒方法”</h4>
<h4>第14條:理解“類對象”的用意</h4>
<h3>第3章 接口與API設(shè)計</h3>
<h4>第15條:用前綴避免命名空間沖突</h4>
<h4>第16條:提供“全能初始化方法”</h4>
<h4>第17條:實(shí)現(xiàn)description方法</h4>
<h4>第18條:盡量使用不可變對象</h4>
<h4>第19條:使用清晰而協(xié)調(diào)的命名方式</h4>
<h4>第20條:為私有方法名加前綴</h4>
<h4>第21條:理解OC錯誤模型</h4>
<h4>第22條:理解NSCopying協(xié)議</h4>
<h3>第4章 協(xié)議與分類</h3>
<h4>第23條:通過委托與數(shù)據(jù)源協(xié)議進(jìn)行對象間通信</h4>
<h4>第24條:將類的實(shí)現(xiàn)代碼分散到便于管理的數(shù)個分類之中</h4>
<h4>第25條:總是為第三方類的分類名稱加前綴</h4>
<h4>第26條:勿在分類中生名屬性</h4>
<h4>第27條:使用“class-continuation分類”隱藏實(shí)現(xiàn)細(xì)節(jié)</h4>
<h4>第28條:通過協(xié)議提供匿名對象</h4>
<h3>第5章 內(nèi)存管理</h3>
<h4>第29條:理解引用計數(shù)</h4>
<h4>第30條:以ARC簡化引用計數(shù)</h4>
<h4>第31條:在dealloc方法中只釋放引用并解除監(jiān)聽</h4>
<h4>第32條:編寫“異常安全代碼”時留意內(nèi)存管理問題</h4>
<h4>第33條:以弱引用避免保留環(huán)</h4>
<h4>第34條:以“自動釋放池塊”降低內(nèi)存峰值</h4>
<h4>第35條:用“僵尸對象”調(diào)試內(nèi)存管理問題</h4>
<h4>第36條:不要使用retainCount</h4>
<h3>第6章 塊與大中樞派發(fā)</h3>
<h4>第37條:理解 "塊"這一概念</h4>
<h4>第38條:為常用的塊類型創(chuàng)建tyoedef</h4>
<h4>第39條:用handler來降低代碼分散程度</h4>
<h4>第40條:用塊引用其所屬對象時不要出現(xiàn)保留環(huán)</h4>
<h4>第41條:多用派發(fā)隊列汰寓,少用同步鎖</h4>
<h4>第42條:多用GCD,少用performSelector系列方法</h4>
<h4>第43條:掌握GCD及操作隊列的使用時機(jī)</h4>
<h4>第44條:通過Dispatch Group機(jī)制跃闹,根據(jù)系統(tǒng)資源狀況來執(zhí)行任務(wù)</h4>
<h4>第45條:使用dispatch_once來執(zhí)行只需要運(yùn)行一次的線程安全代碼</h4>
<h4>第46條:不要使用 dispatch_get_current_queue</h4>
<h3>第7章 系統(tǒng)框架</h3>
<h4>第47條:熟悉系統(tǒng)框架</h4>
<h4>第48條:多用塊枚舉望艺,少用for循環(huán)</h4>
<h4>第49條:對自定義其內(nèi)存管理語義的collection使用無縫橋接</h4>
<h4>第50條:構(gòu)建緩存時選用NSCache而非NSDictionary</h4>
<h4>第51條:精簡initialize與load的實(shí)現(xiàn)代碼</h4>
<h4>第52條:別忘了NSTimer會保留其目標(biāo)對象</h4>