《Effective Objective-C 2.0》之《block和GCD》讀書筆記

理解“塊”這一概念

要點
  • 塊是C担平、C++示绊、Objective-C中的詞法閉包
  • 塊可以接受參數(shù)、也可返回值
  • 塊可以分配在椩萋郏或堆上,也可以是全局的拌禾。分配在棧上的塊可以拷貝到堆里取胎,這樣的話,就和標準的Objective-C對象是一樣的湃窍,具備引用計數(shù)了

關(guān)于塊原理的說闻蛀,可以參加我的文章說說Objective-C中的block

為常用的塊類型創(chuàng)建typedef

要點
  • 以typedef重新定義塊類型,可令塊變量用起來更加簡單
  • 定義新類型時應遵循現(xiàn)有的命名習慣您市,勿使用其名稱與別的類型沖突
    注:用當前類名最為block的前綴名觉痛,防止block名沖突
  • 不妨為同一個塊簽名定義多個類別名。如果要重構(gòu)的代碼使用了塊類型的某個別名茵休,那么只需要修改相應的typedef中的塊簽名即可薪棒,無需改動其他typedef
    注:雖然block內(nèi)容相同手蝎,但是為了以后方便修改坛芽,根據(jù)用途分散block胁艰,用不同的別名

用handler塊降低代碼分散程度

要點
  • 在創(chuàng)建對象時兔毙,可以使用內(nèi)聯(lián)的handler塊將相關(guān)業(yè)務邏輯一并聲明
    注:相當于使用AFNetworking的block回調(diào)
  • 在有多個實例需要監(jiān)控時徙邻,如果采用委托模式帅矗,那么經(jīng)常需要根據(jù)傳入的對象來切換鹅巍,而若改用handler塊來實現(xiàn)臀突,則可直接將塊與相關(guān)對象放在一起
    注:相當于以前使用ASHttpRequest時港谊,如果一個UIController中使用ASI發(fā)了多個請求贸营,則需要在其請求回調(diào)中吨述,根據(jù)請求的tag來區(qū)分請求,這樣請求回調(diào)代理里就會隨著請求的增多變得愈發(fā)混亂
  • 設計API時钞脂,如果用到了handler塊锐极,那么可以增加一個參數(shù),使調(diào)用者可通過此參數(shù)來決定應該把塊安排在哪個隊列上執(zhí)行

用塊引用其所屬對象時不要出現(xiàn)循環(huán)引用

要點
  • 如果塊所捕獲的對象直接或者間接地保留了塊本身芳肌,那么就得當心循環(huán)引用問題
  • 一定要找個適當?shù)臅r機接觸循環(huán)引用灵再,而不能把責任推給API的調(diào)用者。
    注:如可以使用以下代碼亿笤,回調(diào)結(jié)束后翎迁,強制將completionHandler屬性清理干凈。
 - (void)p_requestCompleted {
    if (_completionHandler) {
       _completionHandler(_downloadedData);
    }
    self.completionHandler = nil;
}

關(guān)于block循環(huán)引用的問題净薛,可見iOS中block的循環(huán)引用問題

多用派發(fā)隊列汪榔,少用同步鎖

要點
  • 派發(fā)隊列可用來表述同步語義,這種做法要比使用@synchronized塊或者NSLock對象更簡單
  • 將同步與異步派發(fā)結(jié)合起來肃拜,可用實現(xiàn)與普通加鎖機制一樣的同步行為痴腌,而這么做卻不會阻塞執(zhí)行異步派發(fā)的線程
  • 使用同步隊列以及柵欄塊,可用令同步行為更加高效燃领。

關(guān)于同步問題士聪,可以參加我文檔文章更高效的同步鎖-GCD 同步鎖

多用GCD,少用performSelector系列方法

要點
  • performSelector系列方法在內(nèi)存管理方面容易有疏失猛蔽。它無法確定將要執(zhí)行的選擇子具體是什么剥悟,因而ARC編譯器也就無法插入適當?shù)膬?nèi)存管理方法
    注:,如下代碼ARC編譯器就無法插入適當?shù)膬?nèi)存管理方法
SEL selector;
    if (/* some condition*/) {
        selector = @selector(foo);
    } else if (/* some other condition */) {
        selector = @selector(bar);
    } else {
        selector = @selector(baz);
    }
    id ret = [object performSelector:selector];```
* performSeletor系列方法所能處理的選擇子太過局限了曼库,選擇子的返回值類型以及發(fā)送給方法的參數(shù)個數(shù)受到限制
* 如果想把任務放在另一個線程上執(zhí)行区岗,那么最好不要用perfomSelector系列方法,而是應該把任務封裝到塊里毁枯,然后調(diào)用GCD相關(guān)的方法來實現(xiàn)
**注:**perfomSelector沒辦法指定執(zhí)行的線程

####掌握GCD以及操作隊列的使用時機
#####要點:
* 在解決多線程與任務管理問題時慈缔,派發(fā)隊列并非唯一解決方案
* 操作隊列提供了一套高層的Objective-C API,能實現(xiàn)純GCD所具備的絕大多數(shù)部分功能种玛,而且還能完成一些更為復雜的操作藐鹤,那些操作若改用GCD來實現(xiàn)瓤檐,則需要另外編寫代碼

**針對于NSOperation,可以參見[iOS多線程之NSOperationQueue](http://www.reibang.com/p/52fe1b85c404)**

####通過Dipatch Group機制教藻,根據(jù)系統(tǒng)資源狀況來執(zhí)行任務
#####要點
* 一系列任務可歸入一個dispathc group之中距帅。開發(fā)者可用在這組任務執(zhí)行完畢時獲得通知
* 通過disaptch group,可以在并發(fā)式派發(fā)隊列里同時執(zhí)行多項任務括堤。此時GCD會根據(jù)系統(tǒng)資源狀況來調(diào)度這些并發(fā)執(zhí)行的任務碌秸。開發(fā)者若自己實現(xiàn)此功能,則需要編寫大量代碼

**關(guān)于dispatch group的詳細說明悄窃,
可以參照[[iOS 多線程GCD之dispatch_group](http://www.reibang.com/p/6faea7ef35bc)](http://www.reibang.com/p/6faea7ef35bc)**

####使用dispatch_once來執(zhí)行只需運行一次的線程安全代碼
#####要點
* 經(jīng)常需要編寫”只需要執(zhí)行一次的線程安全代碼“讥电,通過GCD所提供的dispatch_once函數(shù),很容易就能實現(xiàn)此功能
**注:**diapatch_once最常用于單例的創(chuàng)建
* 標記應該聲明static或global作用域轧抗,這樣的話恩敌,在把只需要執(zhí)行一次dispatch_once函數(shù)時,傳進去的標記也是相同的
**注:**使用static是因為每次調(diào)用時都必須使用完全相同的標記横媚,如果不使用static或者global纠炮,那就達不到只執(zhí)行一次的效果了

####不要使用diaptch_get_current_queue
#####要點
* dispatch_get_current_queue函數(shù)的行為常常與開發(fā)者所預期的不同。此函數(shù)已經(jīng)廢棄灯蝴,只應做調(diào)試只用恢口。
* 由于派發(fā)隊列是按層級來組織的,所以無法單用某個隊列隊形來描述“當前隊列”這一概念
* dispatch_get_current_queue函數(shù)用于解決由不可重入的代碼所引起的死鎖穷躁,然而能用此函數(shù)解決的問題耕肩,通常也能用“隊列特定數(shù)據(jù)”來解決

**關(guān)于diaptch_get_current_queue,之后會有專門的文章進行講解**
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末问潭,一起剝皮案震驚了整個濱河市猿诸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狡忙,老刑警劉巖梳虽,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異去枷,居然都是意外死亡怖辆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門删顶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淑廊,你說我怎么就攤上這事逗余。” “怎么了季惩?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵录粱,是天一觀的道長腻格。 經(jīng)常有香客問我,道長啥繁,這世上最難降的妖魔是什么菜职? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮旗闽,結(jié)果婚禮上酬核,老公的妹妹穿的比我還像新娘。我一直安慰自己适室,他們只是感情好嫡意,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捣辆,像睡著了一般蔬螟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汽畴,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天旧巾,我揣著相機與錄音,去河邊找鬼忍些。 笑死鲁猩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的坐昙。 我是一名探鬼主播绳匀,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼炸客!你這毒婦竟也來了疾棵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤痹仙,失蹤者是張志新(化名)和其女友劉穎是尔,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體开仰,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡拟枚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了众弓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恩溅。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谓娃,靈堂內(nèi)的尸體忽然破棺而出脚乡,到底是詐尸還是另有隱情,我是刑警寧澤滨达,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布奶稠,位于F島的核電站俯艰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锌订。R本人自食惡果不足惜竹握,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辆飘。 院中可真熱鬧啦辐,春花似錦、人聲如沸劈猪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽战得。三九已至充边,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間常侦,已是汗流浹背浇冰。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留聋亡,地道東北人肘习。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像坡倔,于是被迫代替她去往敵國和親漂佩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

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