1.熟悉系統框架
將一系列代碼封裝成動態庫(dynamic library),并在其中放入描述其接口的頭文件,這樣做出來的東西就叫框架.
系統的一些常見框架:
CFNetwork 此框架提供了 C 語言級別的網絡請求,它將"BSD 套接字"(BSD socket)抽象成易于使用的網絡接口.
CoreAudio 該框架所提供的 C 語言 API 可用來操作設備上的音頻硬件.
AVFoundation 此框架所提供的 Objective-C 對象可用來回放并錄制音頻及視頻,比如能夠在 UI 視圖類里播放視屏.
CoreData 此框架所提供的 Objective-C 接口可以將對象放入數據庫,便于持久化保存.
CoreText 此框架提供的 C 語言接口可以高效執行文字排版及渲染操作.
許多系統框架都可以直接使用.其中最重要的是 Foundation 與 CoreFoundation, 這兩個框架提供了構建應用程序所需要的許多核心功能.
請記住:用純 C 寫成的框架與用 Obecjtive-C 寫成的一樣重要,若想成為優秀的 Objective-C 開發者,應該掌握 C 語言的核心概念.
2.多用塊枚舉,少用 for 循環
- for 循環,這是最基本的循環方法,因而功能也非常有限.
- 使用 Objective-C1.0的 NSEnumerator 來遍歷: NSEnumerator是個抽象類,提供了兩個方法
- (NSArray *)allObejcts
- (id)nextObject
- 快速遍歷, for in :如果某個類的對象支持快速遍歷,那么就可以宣城自己遵從了名為 NSFastEnumerator 的協議,從而開發者可以采用次語法來迭代該對象.此協之定義了一個方法:
- (NSUInteger)countByEnumeratingWithState:
(NSFastEnumerationSate *)state
object:(id *)stackbuffer
count:(NSUInteger)length
- 基于塊的遍歷方式:此方法大大勝于其他方式的地方在于:遍歷時可以直接獲取更多信息.
- 遍歷 collection 有四種方法.最基本的辦法就是 for 循環,其次是NSEnumerator 遍歷法及快速遍歷法,最新,最先進的方式是"塊枚舉法".
- "塊枚舉法"本身就能通過 GCD 來并發執行遍歷操作,無需另行編寫代碼.而采用其他遍歷方法則無法輕易實現這一點.
- 若提前知道呆遍歷的 collection 含有的何種對象,則應該改塊簽名,指出對象的具體類型.這樣編譯器就可以檢測出開發者是否調用了該對象不具備的方法,并在發現這種問題時報錯.
3.對自定義其內存管理的 collection 使用無縫橋接
- 使用"無縫橋接(toll-free-bridging)"技術,可以在定義與 Foundation 框架中的 Obejctive-C 類和定義 CoreFoundation 框架中的 C 數據結構之間互相轉換.
- __brige 本身的意思是: ARC 仍然具備這個 Obejctive-C 對象的所有權,而 __bridge retained 則相反,意味著 ARC 將交出對象的所有權.
- 在 CoreFoundation 層面創建 collection 時,可以指定許多回調函數,這些函數表示此 collection 應如何處理其元素.然后,可運用無縫橋接技術,將其轉換成具備特殊內存管理語義的 Objective-C collection.
4.構建緩存時選用 NSCache而非 NSDicationary
- NSCache 勝過 NSDictionary 之處于,當系統資源將要耗盡時,它可以自動刪減緩存. NSCache 會先行刪減"最久未使用的(lease recently used)"對像.
- 實現緩存時應選用 NSCache 而并非 NSDicationary 對象,因為 NSCache 可以提供優雅的,自動刪減功能,而且是"線程安全的",此外,它與字典不同,并不會拷貝鍵.
- 可以給 NSCache 對象設置上限,用以限制緩存中的對象總個數及"總成本",而這些尺度則定義了緩存刪減其中對象的時機.但是絕對不要把這些尺度當成可靠的"硬限制(hard limit)",它們僅對 NSCache 起指導作用.
- 如果緩存使用得當,那么應用程序的響應速度就能提高.只有那種狗"重新計算起來費事"數據,才值得放入緩存,比如那些需要從網絡獲取或從磁盤讀取的數據.
5.精簡 initialize 與 load 的實現方法
- (void)load 對于加運行系統的每個類(class)和分類(catergory)來說,必定會調用此方法,而且僅調用一次.
- initialize 方法只應該用來設內部數據,不應該在其中調用其他方法,即便是本類方法,也最好不要調用.
- 在加載階段,如果實現了 load 方法,那么系統會調用它.分類也可以定義此方法,類的 load 方法要比分類的先調用.去其他方法方法不同, load 方法不參與覆寫機制.
- 首次使用某個類之前,系統會向其發送 initialize 消息.由于此方法遵循普通的覆寫規則,所以通常應該在里面判斷當前要初始化的是那個類.
- load 與 initialize 方法都應該實現得精簡一些,這有助于應用程序的響應能力,也能減少引入"依賴環(interdependency cycle)"的幾率.
- 無法在編譯期設定的全局變量,可以放在 initialize 方法里面設置.
6.別忘了 NSTimer 會保留其目標對象
- 計時器要和"運行循環(run loop)"相關聯,運行循環到時候回觸發任務.創建NSTimer 時,可以將其"預先安排"在當前的運行循環中,也可以先創建好,然后由開發者自己來調度.
- NSTimer對象會保留其目標對象,直到計時器失效為止,調用 invalidate 方法可令計時器失效,另外,一次性的計時器在觸發完任務后也會失效.
- 反復執行任務的計時器(repeating timer),很容易引入保留環,如果這種計時器的目標對象又保留了計時器本身,那肯定會導致保留環.真陽環狀保留關系,可能是直接發生的,也可能是通過對象圖里的其它對象間接發生的.
- 可以擴充 NSTimer 的功能,用"塊"來打破保留環.不過,除非 NSTimer 將來在公共接口里提供此功能,否則必須創建分類,將相關實現代碼加入其中.