1.OC使用動(dòng)態(tài)綁定的消息結(jié)構(gòu)枢舶,在運(yùn)行時(shí)才會(huì)檢查對(duì)象類型
接受消息后,要執(zhí)行什么代碼替久,由運(yùn)行期環(huán)境而非編譯器決定
對(duì)于多態(tài)的方法凉泄,將在運(yùn)行期按照虛方法表查出到底應(yīng)該執(zhí)行哪個(gè)函數(shù)的實(shí)現(xiàn)
分配在堆中的內(nèi)存(eg.對(duì)象)必須直接管理,分配在棧上用于保存變量的內(nèi)存在棧幀彈出時(shí)自動(dòng)清理
2.多使用字面量語法創(chuàng)建 @表示字面量
字符串 @“1” 數(shù)值@1 數(shù)組@[@"1",@"2"] 字典@{@"age":@28}
多使用取下標(biāo)操作訪問數(shù)組或字典元素蚯根,如array[1]后众、dictionary[@"age"]
3.使用NS_ENUM 與 NS_OPTIONS 宏定義枚舉類型
指明其底層數(shù)據(jù)類型胀糜,可確保枚舉為所選的底層數(shù)據(jù)類型實(shí)現(xiàn)的
NS_ENUM 枚舉間不需要相互組合
NS_OPTIONS 按位或操作來組合的枚舉,各選項(xiàng)定義為2的冪
在處理枚舉類型的switch語句中不要實(shí)現(xiàn)default分支
//預(yù)定義將源代碼中的ANIMATION_DURATION替換為 0.3?
#define ANIMATION_DURATION 0.3?
//這樣聲明的變量帶有類型信息蒂誉,描述了常量的含義
?static const NSTimeInterval kAnimationDuration = 0.3;
常見關(guān)鍵字:
const 聲明只讀變量教藻,表示將對(duì)象轉(zhuǎn)換成一個(gè)常量,若試圖修改由const 修飾的變量右锨,編譯器會(huì)報(bào)錯(cuò)
static 聲明靜態(tài)變量括堤,意味著該變量?jī)H在定義此變量的.m文件中可見
extern 聲明變量會(huì)出現(xiàn)在全局符號(hào)表中,其他文件可見
typedef 用以給數(shù)據(jù)類型取別名
union 聲明共用數(shù)據(jù)類型
volatile 說明變量在程序執(zhí)行中可被隱含地改變
4.向前聲明
在A中引用B绍移,在A的頭文件中寫 @class B悄窃;實(shí)現(xiàn)文件中再#import "B.h"
5.對(duì)象 — 基本構(gòu)造單元
@property = ivar + getter + setter;
除了生成方法代碼 getter、setter 之外蹂窖,編譯器還要自動(dòng)向類中添加適當(dāng)類型的實(shí)例變量轧抗,并且在屬性名前面加下劃線,以此作為實(shí)例變量的名字瞬测。
通過對(duì)象横媚,存儲(chǔ)并傳遞數(shù)據(jù),在對(duì)象之間傳遞數(shù)據(jù)并執(zhí)行任務(wù)叫做消息傳遞
將所需數(shù)據(jù)保存為各種實(shí)例變量月趟,屬性用于封裝對(duì)象中的數(shù)據(jù)
@synthesize 關(guān)鍵字用來指定實(shí)例變量的名字
@dynamic 關(guān)鍵字告訴編譯器不要自動(dòng)創(chuàng)建實(shí)現(xiàn)屬性所用的實(shí)例變量灯蝴,也無需創(chuàng)建存取方法
6.直接訪問實(shí)例變量 _firstName 不會(huì)調(diào)用其“設(shè)置方法”,不會(huì)觸發(fā)KVO
訪問屬性 self.firstName
寫入實(shí)例變量時(shí)狮斗,通過其“設(shè)置方法” self.
讀取實(shí)例變量時(shí)绽乔,直接訪問實(shí)例變量 _
若采用懶加載(屬性不常用,且創(chuàng)建屬性的成本較高碳褒,所以延遲加載)
必須通過讀取屬性 self.
7.對(duì)象等同性
== 操作比較的是兩個(gè)指針本身
若想檢測(cè)對(duì)象等同性折砸,重寫 isEqual:和 hash 方法
8.類族模式可將實(shí)現(xiàn)細(xì)節(jié)隱藏在一套簡(jiǎn)單的公共接口后面
9.在既有類中使用關(guān)聯(lián)對(duì)象存放自定義數(shù)據(jù)
單純用繼承的方法擴(kuò)展屬性,有時(shí)可能無法創(chuàng)建自己所寫子類
給對(duì)象關(guān)聯(lián)其他對(duì)象沙峻,用鍵區(qū)分屬性
//存取方法
void objc_setAssociatedObject(idobject,void*key,idvalue,objc_AssociationPolicypolicy);
objc_getAssociatedObject(idobject,void*key);
10.objc_msgSend
OC動(dòng)態(tài)性:所有的方法在底層都是普通的C語言函數(shù)睦授,對(duì)象收到消息之后,究竟該調(diào)用哪個(gè)方法摔寨,完全在運(yùn)行期決定去枷,也可在運(yùn)行期改變
此函數(shù)會(huì)依據(jù)接收者與選擇子的類型來調(diào)用適當(dāng)方法
現(xiàn)在接收者所屬的類中搜索其方法列表,找到則執(zhí)行是复,找不到沿著繼承體系向上查找删顶,找到后執(zhí)行;若還是找不到淑廊,執(zhí)行消息轉(zhuǎn)發(fā)
每個(gè)類中都有一張表格逗余,選擇子為查表時(shí)所用的鍵
11.消息轉(zhuǎn)發(fā) objc _msgForward
12.類的方法列表會(huì)把選擇子的名稱映射到相關(guān)的方法實(shí)現(xiàn)上 SEL —> IMP
13.程序運(yùn)行到斷點(diǎn)處,開發(fā)者可向console輸入命令季惩,po 對(duì)象打印
14.每個(gè)OC對(duì)象實(shí)例都是指向某塊內(nèi)存數(shù)據(jù)的指針录粱,所以聲明變量時(shí)腻格,類型后跟一個(gè) * 字符
在運(yùn)行期檢視對(duì)象類型 —> 類型信息查詢,可查出對(duì)象是否能響應(yīng)某個(gè)選擇子啥繁,是否遵從某項(xiàng)協(xié)議菜职,位于類繼承體系的哪一部分
每個(gè)對(duì)象結(jié)構(gòu)體的首個(gè)成員是Class類的變量,定義了對(duì)象所屬的類旗闽,稱 isa 指針酬核,類型信息查詢中使用isa指針獲取對(duì)象所屬的類
15.為類提供一個(gè)全能初始化方法,其他的初始化方法都要調(diào)用它
提供類的全能初始化方法宪睹,當(dāng)?shù)讓訑?shù)據(jù)存儲(chǔ)機(jī)制改變時(shí)愁茁,只需修改此代碼蚕钦,無需改動(dòng)其他初始化方法
每個(gè)類的全能初始化方法都應(yīng)調(diào)用其超類的對(duì)應(yīng)方法
16.盡量創(chuàng)建不可變的對(duì)象
為私有方法名加前綴亭病,將其同公共方法區(qū)分開
OC的動(dòng)態(tài)性使其無法再編譯時(shí)就確定哪個(gè)方法公用,哪個(gè)方法私有嘶居,要在運(yùn)行時(shí)罪帖,運(yùn)行期檢查對(duì)象能響應(yīng)的方法
17.只有發(fā)生了可使整個(gè)應(yīng)用崩潰的嚴(yán)重錯(cuò)誤時(shí),才應(yīng)使用異常
在出現(xiàn)非致命錯(cuò)誤時(shí)邮屁,處理為讓方法返回nil / 0
用NSError處理
Error domain 錯(cuò)誤范圍 整袁、產(chǎn)生錯(cuò)誤的根源
Error code 錯(cuò)誤碼
User info 用戶信息
通過委托協(xié)議來傳遞此錯(cuò)誤,或經(jīng)“輸出參數(shù)”返回給調(diào)用者
- (BOOL)doSomething:(NSError**)error; //error是個(gè)指針佑吝,且該指針本身又指向另外一個(gè)指針?
NSError *error = nil;
Bool ret = [object doSomething:&error];
if(error){...} //若不關(guān)注具體出錯(cuò)原因坐昙,直接判斷ret即可if(ret){...}
18.NSCopying協(xié)議/NSMutableCopying協(xié)議
遵循這個(gè)協(xié)議,對(duì)象應(yīng)該實(shí)現(xiàn)如下方法
-(id)copyWithZone:(NSZone*)zone
//可變版本
-(id)mutableCopyWithZone:(NSZone*)zone
對(duì)于一些不可變對(duì)象芋忿,copy直接賦予對(duì)象的引用炸客,保證一致性,因?yàn)椴恢匦麻_辟空間戈钢,節(jié)約內(nèi)存痹仙;但是對(duì)于可變對(duì)象,copy將重新生成一個(gè)一模一樣的對(duì)象殉了,各改各的开仰,防止造成數(shù)據(jù)錯(cuò)亂。
簡(jiǎn)單做個(gè)試驗(yàn)薪铜,對(duì)字符串進(jìn)行copy众弓、mutableCopy,對(duì)可變字符串進(jìn)行copy隔箍、mutableCopy后谓娃,輸出其地址
驗(yàn)證copy、mutableCopy
可以發(fā)現(xiàn)鞍恢,對(duì)于不可變對(duì)象傻粘,copy會(huì)直接賦予對(duì)象的引用每窖,不生成新對(duì)象,而對(duì)于不可變對(duì)象弦悉,copy窒典、mutableCopy都會(huì)生成新對(duì)象。
19.通過委托和數(shù)據(jù)源協(xié)議進(jìn)行對(duì)象間通信
用 respondsToSelector: 來判斷委托對(duì)象是否實(shí)現(xiàn)了相關(guān)方法
調(diào)用 delegate 對(duì)象中的方法時(shí)稽莉,應(yīng)該把發(fā)起委托的實(shí)例也一并傳入方法中
20.分類的目的在于擴(kuò)展類的功能瀑志,而非封裝數(shù)據(jù)
- 向無源碼的既有類中新增功能
- 分類不支持添加屬性和成員變量,勿在分類中聲明屬性污秆,應(yīng)把封裝數(shù)據(jù)所用的全部屬性都定義在主接口里
- 若在分類中聲明屬性劈猪,需要將其聲明為@dynamic,存取方法等到運(yùn)行期再提供
- 分類中的方法是在運(yùn)行期系統(tǒng)將分類方法加入類良拼,直接添加在類里面的战得,類似于類的固有方法
- 將類的實(shí)現(xiàn)代碼分散到便于管理的數(shù)個(gè)分類之中
- 通過給分類加前綴、給分類中的方法名加前綴的方法庸推,避免分類與分類常侦,分類與本來的類方法覆蓋
21.m 文件中的@interface 叫 class-continuation分類
將私有方法的原型、類中所遵循的不為人知的協(xié)議 在class-continuation中聲明
.mm 擴(kuò)展名表示編譯器將此文件按Objective-C++來編譯
在Objective-C中贬媒,runtime會(huì)自動(dòng)調(diào)用每個(gè)類的兩個(gè)方法聋亡,兩個(gè)方法都只會(huì)被調(diào)用一次。
+(void)load會(huì)在類初始加載時(shí)調(diào)用
+(void)initialize惰性調(diào)用际乘。
保證在足夠早的時(shí)間點(diǎn)被調(diào)用,將
didFinishLaunchingWithOptions 中的第三方中的注冊(cè)代碼坡倔、推送初始化方法挪到+ (void)load 中