Objective-C《編寫高質(zhì)量代碼》筆記

編寫高質(zhì)量代碼是所有程序員的追求余耽,《編寫高質(zhì)量代碼》這本書對于改善Objective-C程序給了61建議惶凝。下面是個人的筆記蝉稳。

1.盡量使用const、enum來替換預(yù)處理#define

相對于字符串字面量或數(shù)字涮总,使用用常量來定義。
例如:

 statis NSString *const kPageRefreshNotification = @"PageRefreshNotification";
 statis const CGFloalt kTableViewHeight = 50.0;

enum兼有#define和const的所有優(yōu)點祷舀,但只能用在整型中瀑梗,所以在定義一個整型時,可以考慮使用枚舉(enum)
例如:

enum{
   MY_INT_CONST = 12345,
}

要點:
(1)盡量避免使用#define預(yù)處理命令裳扯。#define預(yù)處理命令不包括任何類型信息抛丽,僅僅是在編譯前做替換操作。他們在重復(fù)定義是不會發(fā)出警告饰豺,容易在整個程序中產(chǎn)生不一致的值亿鲜。
(2)在源文件(.m)中定義static const 類型常量應(yīng)為無需全局引用,所以他們的名字不需要包含命名空間冤吨。
(3)在頭文件(.h)中定蒿柳;已的全局引用的常量,需要關(guān)聯(lián)定義在源文件(.m)中的部分漩蟆。因為需要被全局引用垒探,所以他們的名字需要包含命名空間,通常用他們的類名作為命名前綴怠李。
(4)盡量用ES_ENUM和NS_OPTIONS宏來實現(xiàn)枚舉圾叼。

2.利用鍵-值機制訪問類的私有成員變量和方法

在Objective-C中仔引,類的成員變量或方法是沒有絕對私有的,可以借助“runtime”機制進(jìn)行對他們訪問褐奥,鍵-值機制有三個常見的成員——鍵-值綁定(KVB)咖耘、鍵-值編碼(KVC)和鍵-值觀察(KVO)

KVC(Key-Value-Coding)

KVC主要利用一種使用字符串標(biāo)識符,間接訪問對象屬性的機制撬码,它是很多技術(shù)的基礎(chǔ)儿倒。主要有(setValue:forKey,valueForKey)和(setValue:forKeyPath呜笑,valueForKeyPath)兩種方法夫否。這兩種方法的使用用途,可以通過如下的代碼來體現(xiàn):

@interface Phone
{
  NSStirng * phoneName;
}
@end

@interface Person
{
  NSStirng* myName;
  Phone *myPhone叫胁;  
}
@end

@implementation Person

Phone *iPhone = ..... //phone對象
Person *xiaoming = ....//person對象

NSString *s1 = [iPhone valueForKey:@"phoneName"];
NSString *s2 = [xiaoming valueForKey:@"myName"];

NSString *s4 = [xiaoming valueForKeyPath:@"myPhone.phoneName"];//正確?
NSString *s5 = [xiaoming valueForKey:@"myPhone.phoneName"];//錯誤?

@end

注意:valueForKeyPath的值是一個路徑(路徑之間以點.分割)凰慈,比如數(shù)據(jù)成員就是對象自己,尋值過程就會向下深入下去驼鹅。
KVC實現(xiàn)原理是運用一個isa-swizzing技術(shù)微谓。isa-swizzing就是類型混合指針機制,KVC通過isa-swizzing來實現(xiàn)其內(nèi)部定位输钩。
isa指針指向的是對象的類豺型,這個類也是一個對象,有自己的權(quán)限买乃。是根據(jù)類的定義編譯而來姻氨。類對象負(fù)責(zé)維護(hù)一個方法調(diào)度表,非標(biāo)本職上是指向類方法的指針組成的剪验;類對象中還保留一個基類的指針肴焊,該指針又有自己的方法調(diào)度表和基類(還有所有通過集成得到的公共和保護(hù)的實例變量)。isa指針對消息分發(fā)機制和Cocoa對象的動態(tài)能力很關(guān)鍵功戚。
例如下面的一行KVC代碼:

[dict setValue:@"hello" forKey:@"nihao"];
就會被處理器編譯成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (dict->isa,sel);
method(dict,sel,@"hello",@"nihao");
KVO(Key-Value Observing)

KVO通過實現(xiàn)名為NSKeyValueObserving的非正式協(xié)議娶眷,其作用是使對象可以將自己注冊為其它對象的觀察者。但被觀察對象的屬性之一發(fā)生改變時疫铜,會直接通知對應(yīng)的觀察者茂浮。Cocoa為遵循KVO對象的每個屬性,都實現(xiàn)了自動觀察者通知機制壳咕。
使用KVO席揽,通常遵循如下流程:
1)注冊與解除注冊

- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;

這三個方法的定義在Foundation/NSKeyValueObserving.h中,NSObject谓厘、NSArray幌羞、NSSet均實現(xiàn)以上方法,因此我們不僅可以觀察普通對象竟稳,還可以觀察數(shù)組和集合類對象属桦。注意熊痴,不要忘了解除注冊,否則會造成資源泄漏聂宾。
2)處理變更通知
當(dāng)被觀察這類對象中的某個屬性發(fā)生變更時果善,光插著需要處理接收到的變更通知。在觀察類中系谐,需要實現(xiàn)名為NSKeyValueObserving的category方法:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context;

其中巾陕,change這個字典保存了哪些變更的信息取決于注冊時的NSKey-ValueObserving-Options

typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {
    
    NSKeyValueObservingOptionNew = 0x01,
    NSKeyValueObservingOptionOld = 0x02,
    NSKeyValueObservingOptionInitial NS_ENUM_AVAILABLE(10_5, 2_0) = 0x04,
    NSKeyValueObservingOptionPrior NS_ENUM_AVAILABLE(10_5, 2_0) = 0x08

};

3)手動或者自動實現(xiàn)KVO通知
KVO機制提供兩種變更消息通知模式:手動和自動實現(xiàn)。在NSKeyValueObservingCustiomization的category中有方法:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;

默認(rèn)情況下纪他,KVO是自動實現(xiàn)的鄙煤。其會自動調(diào)用NSKeyValueObserverNotification的category方法:

- (void)willChangeValueForKey:(NSString *)key;
- (void)didChangeValueForKey:(NSString *)key;
或:
- (void)willChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;
- (void)didChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key;
又或:
- (void)willChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;
- (void)didChangeValueForKey:(NSString *)key withSetMutation:(NSKeyValueSetMutationKind)mutationKind usingObjects:(NSSet *)objects;
KVB(Key-Value Binding)

KVB負(fù)責(zé)建立對象之間的綁定關(guān)系,以及移除和公布這種綁定關(guān)系茶袒。它用了幾個非正式的協(xié)議梯刚。屬性的綁定必須制定一個對象和一個指向該屬性的鍵路徑。
KVB實現(xiàn)的兩個基本方法如下薪寓。
(1)為對象添加觀察者:

 OBserver addObserver:forKeyPath:(NSString *)keyPath options: context:;

(2) 觀察者OBserver收到信息的處理函數(shù)

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context

KVB和KVO最明顯的使用場景就是在一些界面實時顯示很強的地方亡资,如股票走向、售票余額等预愤,這種方式免去了自己操作通知的麻煩沟于。
要點:
(1)在Objective-C中,類的成員變量或方法是沒有絕對私有的植康,可以借助”編譯運行時“機制,即”瞎子摸黑“機制來實現(xiàn)對他們的訪問展懈。
(2)KVC和KVO在定制子類的設(shè)計時特別重要销睁。
(3)KVC、KVO和KVB都支持遍歷存崖。
(4)KVC主要通過isa指針來實現(xiàn)其內(nèi)部查找定位冻记。KVO其設(shè)計基于設(shè)計模式中的”觀察者模式“。KVB和KVO最明顯的使用場景就是在一些界面實時顯示很強的地方来惧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冗栗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子供搀,更是在濱河造成了極大的恐慌隅居,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葛虐,死亡現(xiàn)場離奇詭異胎源,居然都是意外死亡,警方通過查閱死者的電腦和手機屿脐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門涕蚤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宪卿,“玉大人,你說我怎么就攤上這事万栅∮蛹兀” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵烦粒,是天一觀的道長休溶。 經(jīng)常有香客問我,道長撒遣,這世上最難降的妖魔是什么邮偎? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮义黎,結(jié)果婚禮上禾进,老公的妹妹穿的比我還像新娘。我一直安慰自己廉涕,他們只是感情好泻云,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狐蜕,像睡著了一般宠纯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上层释,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天婆瓜,我揣著相機與錄音,去河邊找鬼贡羔。 笑死廉白,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乖寒。 我是一名探鬼主播猴蹂,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼楣嘁!你這毒婦竟也來了磅轻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤逐虚,失蹤者是張志新(化名)和其女友劉穎聋溜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體痊班,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡勤婚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了涤伐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馒胆。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缨称,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出祝迂,到底是詐尸還是另有隱情睦尽,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布型雳,位于F島的核電站当凡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏纠俭。R本人自食惡果不足惜沿量,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冤荆。 院中可真熱鬧朴则,春花似錦、人聲如沸钓简。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽外邓。三九已至撤蚊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間损话,已是汗流浹背侦啸。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丧枪,地道東北人匹中。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像豪诲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挂绰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉屎篱,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評論 0 9
  • 寫在最前面: 這是我讀這本書的第一遍,目前暫定為1.0版本吧葵蒂。很多地方都還沒有很好的理解透徹交播,只是理解到了一點皮毛...
    LaiYoung_閱讀 1,814評論 4 18
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,309評論 0 6
  • 我最近老是看到一些文章講在大學(xué)里很孤獨,然后引起了很多人的共鳴永高,似乎在大學(xué)里孤獨是一種常態(tài)隧土,很多人都有這樣的感覺提针。...
    兔兔紙閱讀 3,796評論 100 129
  • 經(jīng)過8小時的長途跋涉,我們從長沙風(fēng)塵仆仆的到達(dá)了南湖小學(xué)曹傀,我們支教的地方辐脖。一路風(fēng)塵仆仆,一路載歌載舞 經(jīng)過一天...
    大智耶耶耶閱讀 234評論 0 0