Xcode7 中建立靜态庫:.a 和 .framework
一、簡單介紹
1.什麼是庫?
庫是程式代碼的集合,是共享程式代碼的一種方式
2.庫的分類
根據源代碼的公開情況,庫可以分為2種類型
(1)開源庫
公開源代碼,能看到具體實作
比如SDWebImage、AFNetworking
(2)閉源庫
不公開源代碼,是經過編譯後的二進制檔案,看不到具體實作
主要分為:靜态庫、動态庫
二、靜态庫和動态庫
1.靜态庫和動态庫的存在形式
靜态庫:.a 和 .framework
動态庫:.dylib 和 .framework
2.靜态庫和動态庫在使用上的差別
靜态庫:連結時,靜态庫會被完整地複制到可執行檔案中,被多次使用就有多份備援拷貝(圖1所示)
動态庫:連結時不複制,程式運作時由系統動态加載到記憶體,供程式調用,系統隻加載一次,多個程式共用,節省記憶體(圖2所示)
三、靜态庫簡介:
1、靜态庫分為:
真機—Debug(調試)版本、
真機—Release(釋出)版本、
模拟器—Debug版本、
模拟器—Release版本;
開發中一般都打包Release(釋出)版本,将真機和模拟器版本合并,提供外界。
2、使用場景:在項目開發的過程中,例如兩個公司之間業務交流,不可能把源代碼都發送給另一個公司,這時候将私密内容打包成靜态庫,别人隻能調用接口,而不能知道其中實作的細節。
四、用Xcode7建立.a靜态庫
.a檔案版本(以制作SDWebImage靜态庫為例)
1、建立項目,點選iOS—Framework&—Cocoa Touch Static Library。
給你的工程命名為SDWebImageStaticLib
2、系統自動生成以工程名命名的.h和.m檔案,可自定義的在目錄下添加或删除檔案,注意目錄下Products檔案夾有一個.a檔案為紅色,說明檔案并不存在,需要接下來的處理就是将是自己寫的庫檔案中所有的.m檔案都放入.a檔案中私有隐藏起來。
這裡我們将系統生成的.h和.m檔案删除。
3.選中TARGETS下的庫檔案名,建立對外暴露的頭檔案
建立完之後
4.将SDWebImage下的所有檔案導入到SDWebImageStaticLib下
注意:第三步驟和第四步驟是可以調換的,隻不過調換後需要手動的将需要暴露的頭檔案添加進去,是以不調換可以幫助我們完成。
此時預設的情況下,暴露的頭檔案都在Project下,應該移動到Public下
之前:
移動後:
5、然後點選左上角,選擇Edit Scheme,Build Configuration下選擇Release,先注意檢查下面Release是否為NO:Yes表示隻編譯選中模拟器裝置對應的架構,No則為編譯所有模拟器裝置支援的cup架構(Debug版本同理),選擇NO,然後分别在模拟器和真機下Command+B編譯一下,會看到Products檔案夾下的.a檔案變為黑色,這個.a檔案就是我們想要得到的靜态庫,這裡會出現一個問題你先編譯的模拟器會發現.a依然是紅色,你需要模拟器和真機都編譯後.a才會變成黑色,這應該是Xcode本身的問題。
<1>
<2>
<3>
這3步設定完後,選擇真機模式編譯一下,Command + B,此時看到.a靜态庫檔案變成了黑色。
然後将上面的第<3>步改為Debug,再選擇模拟器編譯一下,Command + B,就建立了模拟器環境下的.a檔案,截圖如下一樣。
可以在終端看到,真機Release釋出模式和模拟器Debug測試模式的.a檔案都存在
檔案為:
6、合并真機和模拟器.a檔案,在終端輸入以下指令行:lipo -create 模拟器.a檔案的路徑 真機.a檔案的路徑 -output 合并後的儲存路徑(最終會得到一個合并後的libSDWebImageStaticLib.a檔案,再将暴露出來的.h頭檔案一起複制出來。
7、使用:隻需将libSDWebImageStaticLib.a和暴露出來的.h頭檔案導入工程目錄下就可供外界使用,這樣就很好的保護了自己的實作源代碼,不被他人篡改和偷竊。
8.這裡再補充一下:
<1>.檔案大小.a檔案的體積(一般情況下)
真機用的.a > 模拟器用的.a
所合成.a == 真機用的.a + 模拟器用的.a
<2>.
注:關于靜态庫對CPU架構的支援,首先了解iOS裝置CPU架構方面的知識,ARM是微處理器行業的一家知名企業,arm處理器以體積小和高性能的優勢在嵌入式裝置中廣泛使用,幾乎所有手機都是使用它的。
模拟器:iphone4s~5 : i386 iphone5s~6plus : x86_64
真機:iphone3gs~4s : armv7 iphone5~5c : armv7s (靜态庫隻要支援了armv7,就可以跑在armv7s的架構上) iphone5s~6plus : arm64
armv6, armv7, armv7s是ARM CPU的不同指令集,原則是向下相容的。例如iPhone4S CPU支援armv7, 但它同時相容armv6,隻是使用armv6指令可能無法充分發揮它的特性。
檢視靜态庫.a對處理器架構的支援,先cd到.a檔案的路徑下,指令行輸入:lipo -info xxxxx.a
<3>.
如果庫中還包含了一些資源檔案(如圖檔等),那麼資源檔案也應該放在上面的檔案夾中。
五、用Xcode7建立.framework靜态庫,以MJRefresh為例
1.建立工程并選擇預設Target為Cocoa Touch Framework, 如圖:
2.給你的工程命名為MJRefresh,生成的靜态庫将以标準的名稱格式出現.即MJRefresh.framework
3、項目自動建立設定開放的頭檔案和存放資源的Bundle檔案,可以看到一個紅色的MJRefresh.framework空的靜态庫
4、删除自動生成的MJRefresh.h檔案
5、導入MJRefresh架構中的所有檔案,應該暴露出來的.h檔案預設都在Project下
6、.framework中有些類可能是一些私有的輔助工具,不需要使用者看到,在這裡隻需要把開放出去的類放到Public下, 如圖
7、然後選擇模拟器和Debug模式,編譯一下,Command + B,此時,雖然看到MJRefresh.framework仍為紅色,其實已經生成能在模拟器上運作的.framework靜态庫,進入MJRefresh.framework目錄檔案下,以及使用終端可以看到生成的靜态庫。
選中靜态庫檔案,擷取絕對路徑如下:
在目錄下和終端可以看到生成的靜态庫
8、再選擇真機,設定Release模式,編譯一下,Command + B,此時,雖然看到MJRefresh.framework變成黑色,生成能在真機上運作的靜态庫檔案。
9、我們随意選擇一個靜态庫,點進去看這個庫檔案中的具體内容,可以看到一個MJRefresh可執行二進制的檔案,資源MJRefresh.bundle,暴露出去的頭檔案Headers等
10、下面一步就是合并了,生成模拟器和真機環境下通用的二進制可執行檔案MJRefresh,生成後看一下這個可執行檔案使用的微處理器架構有哪些:
11.好了,合作完成,剩下的就是如何使用這個.framework靜态庫了。
(1)我們可以随意選擇一個生成的MJRefresh.framework,拷貝一下到桌面
(2)然後再将合并後生成的可執二進制檔案MJRefresh拷貝一下,粘貼到桌面上這個MJRefresh.framework檔案中,替換裡面的MJRefresh,生成一個完成的靜态庫。
(3)打開MJRefresh.framework/Modules/module.modulemap檔案,可以看到暴露的MJRefrsh.h檔案被放在umbrella雨傘下保護起來了,是以我們需要将其他的所有暴露的.h檔案放到MJRefresh.h檔案中保護起來,不然會出現警告
(4)我們以為此時大功告成,可以測試代碼了,結果出現如下錯誤:
為什麼會這樣的?因為我們做的是靜态庫,在使用的時候需要額外加一個步驟,要把Framework同時添加到‘Embedded Binaries’中
此時再測試,發現沒問題了,大功告成,可喜可賀!
六、制作靜态庫的注意點
(1)注意:
無論是 .a 靜态庫還是 .framework 靜态庫,最終需要的都是:二進制檔案 + .h + 其它資源檔案
(2).a 和 .framework 的使用差別
.a 本身是一個二進制檔案,需要配上 .h 和 其它資源檔案 才能使用
.framework 本身已經包含了 .h 和 其它資源檔案,可以直接使用
(3)圖檔資源的處理
如果靜态庫中用到了圖檔資源,一般都放到一個bundle檔案中,bundle名字一般跟 .a 或 .framework 名字一緻
bundle的建立:建立一個檔案夾,修改擴充名為 .bundle 即可,右擊bundle檔案,顯示包内容,就可以往bundle檔案中放東西
建議:自己制作的靜态庫中要用到的圖檔資源,不建議直接以png的字尾名方式拖到項目中使用,而是推薦使用放到bundle檔案中。這樣可以避免靜态庫的圖檔名和使用靜态庫的項目中存在的圖檔産生沖突。
1)建立一個檔案夾,把需要打包的資源圖檔放在裡面
例如:
2)修改擴充名為 .bundle,敲回車,點選添加。
(4)多檔案處理
如果靜态庫需要暴露出來的 .h 比較多,可以考慮建立一個主頭檔案(一般 主頭檔案 和 靜态庫 同名)
在主頭檔案中包含所有其他需要暴露出來的 .h 檔案
使用靜态庫時,隻需要#import 主頭檔案
實際上蘋果官方就是這麼做的,例如:#import <UIKit/UIKit.h>
(5).framework為什麼既是靜态庫又是動态庫
系統的 .framework 是動态庫
我們自己建立的 .framework 是靜态庫
(6)靜态庫中包含了Category(分類)
如果靜态庫中包含了Category,有時候在使用靜态庫的工程中會報“方法找不到”的錯誤(unrecognized selector sent to instance)
解決方案:在使用靜态庫的工程中配置Other Linker Flags為-ObjC
程式猿神奇的手,每時每刻,這雙手都在改變着世界的互動方式!
本文轉自當天真遇到現實部落格園部落格,原文連結:http://www.cnblogs.com/XYQ-208910/p/5157673.html,如需轉載請自行聯系原作者