IOS 靜態庫的和.framework制作
什麽是庫?
庫是程序代碼的集合,是共享程序代碼的一種方式
根據源代碼的公開情況,庫可以分為2種類型
開源庫
公開源代碼,能看到具體實現
比如SDWebImage、AFNetworking
閉源庫
不公開源代碼,是經過編譯後的二進制文件,看不到具體實現
主要分為:靜態庫、動態庫
靜態庫和動態庫的存在形式 靜態庫:.a 和 .framework 動態庫:.dylib 和 .framework 靜態庫和動態庫在使用上的區別 靜態庫:鏈接時,靜態庫會被完整地復制到可執行文件中,被多次使用就有多份冗余拷貝(左圖所示) 動態庫:鏈接時不復制,程序運行時由系統動態加載到內存,供程序調用,系統只加載一次,多個程序共用,節省內存(右圖所示)
選擇“Cocoa Touch Static Library”
輸入靜態庫名稱
添加庫需要包含的源代碼
選擇需要暴露出來的.h文件,.m文件會自動編譯到.a文件中
選擇真機設備,然後 Command+B 編譯,libMJRefresh.a文件從紅色變為黑色
選擇模擬器,依然 Command+B ,模擬器和真機環境下用的.a文件是分開的
右擊“Show In Finder”,查看制作好的.a文件
Debug-iphoneos文件夾裏面的東西是用在真機上的
Debug-iphonesimulator文件夾裏面的東西是用在模擬器上的
如果Scheme是Release模式,生成的文件夾就以Release開頭
如果想讓一個.a文件能同時用在真機和模擬器上,需要進行合並
在終端輸入指令
lipo -create Debug-iphoneos/libMJRefresh.a Debug-iphonesimulator/libMJRefresh.a -output libMJRefresh.a
藍色部分是固定指令
紅色、紫色是真機和模擬器.a文件的路徑
橙色是所合成.a文件的路徑
.a文件的體積(一般情況下)
真機用的.a > 模擬器用的.a
所合成.a == 真機用的.a + 模擬器用的.a
通過lipo –info libMJRefresh.a可以查看 .a 的類型(模擬器還是真機)
如何使用.a
直接將.a、.h、資源文件拖拽到其他項目中即可
選擇“OS X”-“Framework & Library”-“Bundle”
輸入靜態庫名稱
剛才是基於OS X創建的工程,所以得修改項目環境為iOS的
修改Packaging
修改Info.plist
註釋掉pch文件的內容
添加庫需要包含的源代碼
添加需要暴露出來的 .h 文件
添加需要暴露出來的 .h 文件,並且放到Public下面
接下來的步驟跟 .a 是一樣的,分別選擇真機和模擬器,Command+B
真機和模擬器下的 .framework 也是分開使用的
生成的framework在Xcode的緩存文件夾中
/Users/用戶名/Library/Developer/Xcode/DerivedData/項目名/Products
可以在終端下使用 lipo 指令合並 .framework, 需要合並的是framework裏面的某個文件
直接拖拽整個 .framework 到其他項目的Frameworks文件夾下
然後包含主頭文件:#import <MJRefresh/MJRefresh.h>
手工制作 .framework 過於復雜,借助開源模板進行制作會比較簡單
模板地址
https://github.com/kstenerud/iOS-Universal-Framework
安裝模板
在終端下進入iOS-Universal-Framework/Fake Framework文件夾
執行指令./install.sh
安裝模板後,完全重啟Xcode
最後將 .framework 的結構調整一下即可
無論是 .a 靜態庫還是 .framework 靜態庫,最終需要的都是:
二進制文件 + .h + 其它資源文件
.a 和 .framework 的使用區別
.a 本身是一個二進制文件,需要配上 .h 和 其它資源文件 才能使用
.framework 本身已經包含了 .h 和 其它資源文件,可以直接使用
圖片資源的處理
如果靜態庫中用到了圖片資源,一般都放到一個bundle文件中,bundle名字一般跟 .a 或 .framework 名字一致
bundle的創建:新建一個文件夾,修改擴展名為 .bundle 即可,右擊bundle文件,顯示包內容,就可以往bundle文件中放東西
多文件處理
如果靜態庫需要暴露出來的 .h 比較多,可以考慮創建一個主頭文件
(一般 主頭文件 和 靜態庫 同名)
在主頭文件中包含所有其他需要暴露出來的 .h 文件
使用靜態庫時,只需要#import 主頭文件
實際上蘋果官方就是這麽做的,例如:#import <UIKit/UIKit.h>
.framework為什麽既是靜態庫又是動態庫
系統的 .framework 是動態庫
我們自己建立的 .framework 是靜態庫
靜態庫中包含了Category
如果靜態庫中包含了Category,有時候在使用靜態庫的工程中會報“方法找不到”的錯誤(unrecognized selector sent to instance)
解決方案:在使用靜態庫的工程中配置Other Linker Flags為-ObjC
IOS 靜態庫的和.framework制作