進行iOS開發已經很久了,但是一直沒有靜下心研究Git上一些大神寫的優秀工程。現在下定決心開始從零開始,仔細研讀並敲寫一遍大神工程。首先我准備研究的是 ibireme 大神的YYKit工程。這個工程比較龐大。而且這是ibireme大神在零散時間敲出的高質量代碼。向大神致敬。
其中包含:
- YYModel — 高性能的 iOS JSON 模型框架。
- YYWebImage — 高性能的 iOS 異步圖像加載框架。
- YYKeyboardManager — iOS 鍵盤監聽管理工具。
- YYDispatchQueuePool — iOS 全局並發隊列管理工具。
- YYAsyncLayer — iOS 異步繪制與顯示的工具。
- YYCategories — 功能豐富的 Category 類型工具庫。
下面附上大神的一句話,與君共勉。
“我花費了大量的時間閱讀和學習各種開源的代碼、研究其中的實現原理、嘗試自己實現相關技術、嘗試在工作中使用,這使得我在 iOS 開發技術上進步很快。自學能力是很重要的。主動去研究一些優秀的開源項目、多在工作中實踐和學習,這樣就能逐步提升個人技術水平了。” ——— ibireme
一、YYCategories結構
現在是最開始,我首先模仿的是YYCategories這個類庫。首先先了解下這個類庫的結構。
它由外面的YYCategories頭文件、YYCategoriesMacro宏和三大類擴展類組成。下面的三類都是基於里面的擴展類所屬的類組成。
(1)YYCategories.h類
這個類是庫的頭文件。它導入了所有的擴展類。使用的時候只要導入本文件就可使用所有擴展。
(2)YYCategoriesMacro.h類
這個類看名字是宏定義類。
(3)Foundation
這里面包含了這些文件。是對這些文件的擴展。下面會一一使用學習。
(4)UIKit
這里面包含了這些文件。是對這些文件的擴展。下面會一一使用學習。
(5)Quartz
這里面包含了這些文件。是對這些文件的擴展。下面會一一使用學習。
二、 YYCategories.h
原本我以為這個頭文件類不會有什么知識點可以get到。結果我還是小瞧了大神的代碼。
tip1:#if __has_include() 判斷文件是否存在,再導入使用,避免文件不存在的情況;
在工程中,我們常常需要導入一些文件,但是萬一什么時候刪掉了工程又太大,工程報錯。這不就很難找嗎。這就有了這個系統宏定義。他首先可以使我們判斷這個文件是否存在再導入。就像下面的代碼。此宏傳入一個你想引入文件的名稱作為參數,如果該文件能夠被引入則返回1,否則返回0。
#if __has_include(<unistd.h>) # include <unistd.h> #elif __has_include(<io.h>) # include <io.h> #else # error "Insane system" #endif
而且他還有其他功能。就是判斷是否導入的是framework來決定導入時選用<>還是""。如下代碼:
#if __has_include(<YYModel/YYModel.h>)#import <YYModel/NSObject+YYModel.h> #import <YYModel/YYClassInfo.h> #else #import "NSObject+YYModel.h" #import "YYClassInfo.h" #endif
這樣做可以提高編譯效率.如果指定文件路徑,則搜索的更快一些.
一般我們使用YYCategories導入的時候都是庫文件,所以指定目錄位置搜索更快一些
#import < > 引用系統文件,它用於對系統自帶的頭文件的引用,編譯器會在系統文件目錄下去查找該文件. #import " " 用戶自定義的文件用雙引號引用,編譯器首先會在用戶目錄下查找,然后到安裝目錄中查
tip2: FOUNDATION_EXPORT
這個是一個宏定義的標志,和#define一樣。
在YYCategories中定義了但是沒有用到。
使用方法:
.h文件中: FOUNDATION_EXPORT NSString * const kTestString; .m文件中: NSString * const kTestString = @"Test"; 功能類似於: #define kTestString @"Test";
優點:
由於過多的宏定義會產生過多的二進制文件,故如果宏定義比較多,建議用FOUNDATION_EXPORT。而且FOUNDATION_EXPORT效率更高,速度較快。
FOUNDATION_EXPORT
直接使用
stringInstance == MyFirstConstant
來比較,比較的是指針地址
define
使用
[stringInstance isEqualToString:MyFirstConstant]
比較字符串的每一個字符是否相等
FOUNDATION_EXPORT
效率更高