Effective Objective-C 讀書筆記(一)

OC的消息機制

OC與其他面向?qū)ο笳Z言如C++踱阿、Java的不同之處在于使用消息機制代替方法調(diào)用吓懈。

// OC
NSObject *obj = [NSObject new];
[obj doSomething];

// Java
Object obj = new Object();
obj.doSomething();

兩者關(guān)鍵區(qū)別在于:在使用方法調(diào)用的語言中架忌,程序運行時所應(yīng)執(zhí)行的代碼多數(shù)情況下在編譯時期就已經(jīng)被確定,只有在多態(tài)的情況下才會在運行時查看該調(diào)用哪段代碼。而在OC中,無論是否多態(tài)模闲,程序運行時所應(yīng)執(zhí)行的代碼都是由運行時環(huán)境來決定。所以在OC中崭捍,編譯器并不關(guān)心接收消息的對象是何種類型尸折,所有消息也都在運行時才被處理,也就是OC的動態(tài)綁定機制殷蛇。

@class的使用

如果在一個類SomeClass的聲明中引用了另一個類OtherClass实夹,最簡單的做法可能是使用#import "OtherClass.h"導(dǎo)入這個類,然而這并不是最好的做法粒梦。
假設(shè)SomeClass又被許多其他類引用亮航,那么每次引用SomeClass的時候都會同時引用OtherClass,這會降低一定的編譯性能匀们。更好的做法是在聲明文件中將#import "OtherClass.h"改為@class OtherClass;缴淋,在具體使用OtherClass的文件如SomeClass.m中,才使用#import "OtherClass.h"導(dǎo)入這個類泄朴。

// SomeClass.h
#import <Foundation/Foundation.h>

// #import "OtherClass.h"
@class OtherClass;

@interface SomeClass : NSObject

@property (nonatomic) OtherClass * other;

@end

這種做法叫做向前聲明重抖,向前聲明還可以解決兩個類相互循環(huán)引用的問題。

向前聲明并不是所有情況都適用祖灰,當(dāng)一個類需要繼承自某個父類時仇哆,就必須在聲明中導(dǎo)入父類的頭文件。同樣夫植,當(dāng)一個類需要遵守某個協(xié)議時讹剔,也必須導(dǎo)入?yún)f(xié)議的頭文件。

字面量語法的使用

Foundation框架中的這幾個類NSString详民、NSNumber延欠、NSArray、NSDictionary都有相應(yīng)的字面量語法沈跨,具體使用如下:

NSString *str = @"some string";
NSNumber *num = @10;
NSArray *arr = @[@"some string", @10];
NSString *someString = arr[0];
NSDictionary *dic = @{@"key1" : @"value1", @"key2" : @"value2"};
NSString *value = dic["key1"];

使用字面量語法不僅可以使代碼簡潔由捎、可讀性強,在數(shù)組和字典的創(chuàng)建過程中饿凛,還有一個小小的優(yōu)點狞玛。

使用字面量語法創(chuàng)建數(shù)組其實本質(zhì)也是調(diào)用NSArray類的arrayWithObjects:方法软驰,前面arr數(shù)組的創(chuàng)建等價于如下代碼:

NSArray *arr = [NSArray arrayWithObjects:@"some string", @10, nil];

使用arrayWithObjects:方法創(chuàng)建數(shù)組時,如果數(shù)組元素中有nil心肪,會提前結(jié)束方法锭亏,不會拋出異常。這樣會導(dǎo)致數(shù)組元素與邏輯不符硬鞍,卻很難發(fā)現(xiàn)代碼錯誤慧瘤。
而使用字面量語法創(chuàng)建數(shù)組時,如果數(shù)組元素中有nil固该,則會拋出異常锅减,這樣有利于程序員提前發(fā)現(xiàn)代碼錯誤。

用類型常量代替#define預(yù)處理指令

寫代碼時經(jīng)常遇到需要使用常量的地方伐坏,一般都不推薦直接使用數(shù)字怔匣,因為它既顯得突兀又不利于代碼的維護,通常我們有兩種辦法來定義常量桦沉,一種是使用#define預(yù)處理命令劫狠,另一種是使用static const關(guān)鍵字來定義一個常量。

#define ANIMATION_DURATION 0.3
static const NSTimeInterval kAnimationDuration = 0.3

使用#define預(yù)處理命令僅僅是將代碼中的ANIMATION_DURATION字符串替換為0.3永部,這樣定義的常量并不具備類型信息独泞,因此無法使用編譯器帶給我們的諸多好處,所以更推薦使用第二種方式定義常量苔埋。

使用static const關(guān)鍵字來定義常量懦砂,用在類的實現(xiàn)文件中,則此常量只作用在本類中组橄,其他類無法使用荞膘。如果多個類都需使用到某一常量,則需將常量定義成公開的玉工,具體方式是在類的聲明文件中使用extern const關(guān)鍵字聲明常量羽资,在類的實現(xiàn)文件中使用const關(guān)鍵字定義常量,這樣任何類只要導(dǎo)入了聲明常量的頭文件就可以直接使用定義好的常量了遵班。

需要注意的是屠升,OC中沒有命名空間的概念,是不允許有多個同名的全局變量存在的狭郑,因此定義公共的常量最好遵守一定的命名規(guī)則腹暖,通常是使用類名作為前綴,如WXGViewAnimationDuration翰萨。

善用枚舉類型來增強代碼的可讀性

OC的系統(tǒng)框架中脏答,大規(guī)模使用了枚舉類型,蘋果官方也推薦開發(fā)者更多去使用枚舉類型來表達一系列常量。這樣做的好處是使代碼更具可讀性殖告,通過枚舉中每個成員的名字可以很清楚地明白它所代表的意義阿蝶。

可以使用typedef關(guān)鍵字定義枚舉類型,來省去每次使用枚舉類型時都需要加上enum關(guān)鍵字的麻煩黄绩。

enum ConnectionState {
    ConnectionStateDisconnected,
    ConnectionStateConnecting,
    ConnectionStateConnected
};

typedef enum ConnectionState ConnectingState;

對于多選枚舉情況羡洁,可以使用按位操作來定義枚舉值,這樣在使用時就可以通過|或&來控制枚舉的選項宝与。

蘋果官方還定義了兩個宏焚廊,用來快速定義使用自定義變量類型的枚舉冶匹,我們也應(yīng)該更多的使用這兩個宏來定義自己的枚舉习劫。具體使用參考如下代碼:

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
    UIViewAnimationTransitionNone,
    UIViewAnimationTransitionFlipFromLeft,
    UIViewAnimationTransitionFlipFromRight,
    UIViewAnimationTransitionCurlUp,
    UIViewAnimationTransitionCurlDown,
};

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};

枚舉類型還經(jīng)常用在switch分支選擇上,這種情況下最好不要在case語句中加上default選項嚼隘,意義在于當(dāng)枚舉中有新成員加入后诽里,因為沒有遍歷所有可能情況,編譯器就會發(fā)出警告飞蛹,從而確保switch語句能夠正確處理所有情況谤狡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市卧檐,隨后出現(xiàn)的幾起案子墓懂,更是在濱河造成了極大的恐慌,老刑警劉巖霉囚,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捕仔,死亡現(xiàn)場離奇詭異,居然都是意外死亡盈罐,警方通過查閱死者的電腦和手機榜跌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盅粪,“玉大人钓葫,你說我怎么就攤上這事∑惫耍” “怎么了础浮?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奠骄。 經(jīng)常有香客問我霸旗,道長,這世上最難降的妖魔是什么戚揭? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任诱告,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘精居。我一直安慰自己锄禽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布靴姿。 她就那樣靜靜地躺著沃但,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佛吓。 梳的紋絲不亂的頭發(fā)上宵晚,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音维雇,去河邊找鬼淤刃。 笑死,一個胖子當(dāng)著我的面吹牛吱型,可吹牛的內(nèi)容都是我干的逸贾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼津滞,長吁一口氣:“原來是場噩夢啊……” “哼铝侵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起触徐,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤咪鲜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后撞鹉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疟丙,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年孔祸,在試婚紗的時候發(fā)現(xiàn)自己被綠了隆敢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡崔慧,死狀恐怖拂蝎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惶室,我是刑警寧澤温自,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站皇钞,受9級特大地震影響悼泌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜夹界,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一馆里、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦鸠踪、人聲如沸丙者。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽械媒。三九已至,卻和暖如春评汰,著一層夾襖步出監(jiān)牢的瞬間纷捞,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工被去, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留主儡,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓编振,卻偏偏與公主長得像缀辩,于是被迫代替她去往敵國和親臭埋。 傳聞我的和親對象是個殘疾皇子踪央,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容