《Effective Objective-C 2.0》 閱讀筆記 3

23. 通過委托與數(shù)據(jù)源協(xié)議進(jìn)行對象間通信

我們實際編碼時已經(jīng)經(jīng)常使用到protocol的技術(shù)了(委托代理模式)

定義代理屬性時,切記使用weak而非strong,避免“保留環(huán)”

@property (nonatomic, weak) id<EOCSomeDelegate> delegate;

24. 將類的實現(xiàn)代碼分散到便于管理的幾個分類中

為了避免一個實現(xiàn)文件太大内斯,實現(xiàn)的方法太多蹦浦,可以根據(jù)功能將類的實現(xiàn)分到不同的分類中篇裁。

EOCPerson類可以分成幾個不同的實現(xiàn)文件:

EOCPerson+Friendship(.h/.m)
EOCPerson+Work(.h/.m)
EOCPerson+Play(.h/.m)

如果要使用分類中的方法,記得引入分類的頭文件肾砂。

這樣分散到分類中的好處是:

  1. 便于調(diào)試,編譯后的符號表中宏悦,分類中的方法符號會出現(xiàn)分類的名稱镐确。
  2. 如果將私有方法放在名為Private的分類中,那很容易看到調(diào)試錯誤原因饼煞,并且在編寫通用庫供他人使用時源葫,私有分類的頭文件不公開,只能程序庫自己能用砖瞧。

25. 為第三方類的分類名稱加前綴

分類機(jī)制常用在向無源碼的類中新增功能息堂。

將分類方法加入源類的操作是在運行期間系統(tǒng)加載分類時完成的。

如果分類中的方法名稱與類中已有的方法名一樣块促,分類中的方法就會覆蓋原來的實現(xiàn)荣堰。解決辦法就是給方法加前綴。

在整個應(yīng)用程序中竭翠,類的每個實例都可以調(diào)用分類的方法振坚。

26. 勿在分類中聲明屬性

除了"class-cotinuation分類",其他分類都無法向類中新增實例變量斋扰,它們無法把實現(xiàn)屬性所需的實例變量合成渡八。

當(dāng)然啃洋,使用關(guān)聯(lián)對象可以解決這種無法合成實例變量的問題:

#import <objc/runtime.h>

static const char *kFriendsPropertyKey = "kFriendsPropertyKey";
@implementation EOCPerson (Friendship)

- (NSArray *)friends {
    return objc_getAssociatedObject(self,kFriendsPropertyKey);
}

- (void)setFriends:(NSArray *)friends {
    objc_setAssociatedObject(self,kFriendsPropertyKey,
                            friends,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

但是這樣不理想,因為內(nèi)存管理語義容易出錯呀狼。萬一你修改了屬性的內(nèi)存管理語義裂允,還要記得在設(shè)置方法中修改關(guān)聯(lián)對象所用的內(nèi)存管理語義。所以不推薦這樣做哥艇。

屬性應(yīng)該都定義在主接口里绝编。分類的目的在于擴(kuò)展功能,而非封裝數(shù)據(jù)貌踏。

27. 使用"class-continuation分類"隱藏實現(xiàn)細(xì)節(jié)

"class-continuation分類"就是我們常寫在實現(xiàn)文件中的這樣一段代碼:

@interface EOCPerson ()
//property here
@end

這樣十饥,可以將方法或者實例變量隱藏在本類中使用,而不暴露給公共接口祖乳。

如果屬性在主接口中聲明為只讀逗堵,而類內(nèi)部又要修改屬性值,就可以在class-continuation分類中將其擴(kuò)展為可讀寫眷昆。

28. 通過協(xié)議提供匿名對象

協(xié)議可以在某種程度上提供匿名類型蜒秤。具體的對象類型可以淡化成遵守某協(xié)議的id類型。

使用匿名對象來隱藏類型名稱亚斋。

如果具體類型不重要作媚,重要的是對象能夠響應(yīng)特定方法,那么可使用匿名對象來表示帅刊。

29. 引用計數(shù)

引用計數(shù)變?yōu)?后“可能”就釋放內(nèi)存了纸泡,其實只是放回“可用內(nèi)存池”,如果沒有被覆寫之前仍然可以訪問赖瞒,但這是很危險的女揭,因為這樣很可能出現(xiàn)野指針,造成程序崩潰栏饮。

弱引用避免保留環(huán)吧兔。

30. 以ARC簡化引用計數(shù)

ARC是會自動執(zhí)行retain、release袍嬉、autorelease的掩驱,所以在ARC模式下是不可以直接調(diào)用內(nèi)存管理方法的,具體如下方法:

  • retain
  • release
  • autorelease
  • dealloc

實際上冬竟,ARC不是通過OC的消息派發(fā)機(jī)制的欧穴,而是直接調(diào)用底層的C語言版本比如objc_retain”门梗可以節(jié)省很多CPU周期涮帘。

若方法名以下列詞語開頭,則返回的對象歸調(diào)用者所有, 即調(diào)用的代碼要負(fù)責(zé)釋放對象笑诅。

  • alloc
  • new
  • copy
  • mutableCopy

若方法名不以上述四個詞語開頭调缨,則表示返回的對象不歸調(diào)用者所有疮鲫,返回的對象會自動釋放。

這些規(guī)則所需要的內(nèi)存管理事宜都有ARC自動處理弦叶。

ARC在運行期還可以起到優(yōu)化作用俊犯, 比如在autorelease之后立馬又調(diào)用retain的場景下,ARC在運行期可以檢測這種多余的操作伤哺,利用全局?jǐn)?shù)據(jù)結(jié)構(gòu)中的一個標(biāo)志位來決定是否需要真正執(zhí)行autorelease和retain操作燕侠。

ARC只負(fù)責(zé)管理OC對象的內(nèi)存,而CoreFoundation對象不歸ARC管理立莉,還需要開發(fā)者適當(dāng)調(diào)用CFRetain/CFRelease绢彤。

31. 在dealloc方法中只釋放引用并解除監(jiān)聽

每個對象生命周期結(jié)束后最終為系統(tǒng)回收,執(zhí)行一次且僅一次dealloc方法蜓耻。

在此方法中釋放對象所擁有的所有引用茫舶,ARC會自動生成.cxx_destruct方法。

此方法還要做一件重要的事情刹淌,就是把配置的observation behavior都清理掉饶氏,比如NSNotificationCenter給此對象訂閱過某種通知,那么應(yīng)該在此注銷有勾。否則繼續(xù)給對象發(fā)送通知的話會導(dǎo)致crash疹启。

- (void)dealloc {
    CFRelease(coreFoundationObject);
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

如果非ARC模式,最后還要調(diào)用[super dealloc]柠衅,ARC模式下就不需要。

對于開銷較大或者系統(tǒng)稀缺的資源(如文件描述符籍琳、套接字菲宴、大塊內(nèi)存等),應(yīng)該使用"清理方法"而非dealloc來釋放趋急。比如網(wǎng)絡(luò)連接使用完畢后喝峦,調(diào)用close方法。
這樣做的原因是:

  1. 避免保留稀缺資源的時間過長呜达。
  2. 系統(tǒng)為了優(yōu)化程序效率谣蠢,不保證每個對象的dealloc方法都被執(zhí)行。

在dealloc中查近,可以檢測資源是否執(zhí)行了清理操作眉踱,沒有的話可以輸出錯誤信息并執(zhí)行一次清理操作。

有些方法不應(yīng)該在dealloc方法里調(diào)用霜威,比如

  • 執(zhí)行異步任務(wù)的方法
  • 需要切換到特定線程執(zhí)行的方法
  • 屬性的存取方法

32. 編寫“異常安全代碼”時留意內(nèi)存管理問題

雖然OC中異常只應(yīng)發(fā)生在嚴(yán)重的錯誤中谈喳,但是有時候還是要編寫代碼來捕獲異常。

在捕獲異常時要管理好內(nèi)存戈泼,防止泄漏婿禽。

比較下面的兩種處理方法赏僧,明顯后者更合適:

(1)

@try {
   EOCSomeClass *object = [[EOCSomeClass alloc] init];
   [object doSomethingThatMayThrow];
   [object release];//此處可能執(zhí)行不到,造成內(nèi)存泄漏
}
@catch (...) {
   NSLog(@"exception");
}

(2)

EOCSomeClass *object;
@try {
   object = [[EOCSomeClass alloc] init];
   [object doSomethingThatMayThrow];
}
@catch (...) {
   NSLog(@"exception");
}
@finally {
   [object release];//此處總會執(zhí)行到扭倾。
}

以上是非ARC模式下的做法淀零,如果是ARC模式也這樣try/catch就有很大問題了,因為ARC針對這種情況不會自動處理release膛壹,這樣做的代價很大驾中。但是ARC還是可以生成安全處理異常所用的代碼,只需要打開-fobjc-arc-exceptions編譯器標(biāo)志恢筝。

所以哀卫,總的來說,如果非ARC模式下必須捕獲異常撬槽,那就設(shè)法保證代碼能把對象清理干凈此改; 如果是ARC下必須捕獲異常,就要打開-fobjc-arc-exceptions標(biāo)志侄柔。當(dāng)然共啃,如果發(fā)現(xiàn)程序有大量異常捕獲操作時,說明你的代碼需要重構(gòu)了暂题。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末移剪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子薪者,更是在濱河造成了極大的恐慌纵苛,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件言津,死亡現(xiàn)場離奇詭異攻人,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)悬槽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門怀吻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人初婆,你說我怎么就攤上這事蓬坡。” “怎么了磅叛?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵屑咳,是天一觀的道長。 經(jīng)常有香客問我弊琴,道長乔宿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任访雪,我火速辦了婚禮详瑞,結(jié)果婚禮上掂林,老公的妹妹穿的比我還像新娘。我一直安慰自己坝橡,他們只是感情好泻帮,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著计寇,像睡著了一般锣杂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上番宁,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天元莫,我揣著相機(jī)與錄音,去河邊找鬼蝶押。 笑死踱蠢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棋电。 我是一名探鬼主播茎截,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赶盔!你這毒婦竟也來了企锌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤于未,失蹤者是張志新(化名)和其女友劉穎撕攒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烘浦,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡抖坪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谎倔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柳击。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡猿推,死狀恐怖片习,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蹬叭,我是刑警寧澤藕咏,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站秽五,受9級特大地震影響孽查,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坦喘,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一盲再、第九天 我趴在偏房一處隱蔽的房頂上張望西设。 院中可真熱鬧,春花似錦答朋、人聲如沸贷揽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽禽绪。三九已至,卻和暖如春洪规,著一層夾襖步出監(jiān)牢的瞬間印屁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工斩例, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留雄人,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓樱拴,卻偏偏與公主長得像柠衍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晶乔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

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