iOS創(chuàng)建.a和.framework靜態(tài)庫,以及Bundle資源文件的使用

轉自https://blog.csdn.net/pangshishan1/article/details/72179898

引言

在開發(fā)中.framework靜態(tài)庫還是比較常見的,比如:SDK,公司間的代碼合作等。我們可以把一些不愿意讓別人見到的代碼,用靜態(tài)庫的方式把它隱藏起來,只留下.h文件顯示方法供編程人員使用。而.a文件出了靜態(tài)庫本身外,還需要引入.h文件,而.framework就不需要如此,由于.framework的方便性所以一般情況下我們見到的較多。

什么是庫

庫從本質上來說是一種可執(zhí)行代碼的二進制格式,可以被載入內存中執(zhí)行。庫分靜態(tài)庫和動態(tài)庫兩種。
iOS中的靜態(tài)庫有 .a 和 .framework兩種形式;動態(tài)庫有.dylib 和 .framework 形式,后來.dylib動態(tài)庫又被蘋果替換成.tbd的形式。

靜態(tài)庫與動態(tài)庫的區(qū)別

靜態(tài)庫和動態(tài)庫是相對編譯期和運行期的:靜態(tài)庫在程序編譯時會被鏈接到目標代碼中,程序運行時將不再需要改靜態(tài)庫;而動態(tài)庫在程序編譯時并不會被鏈接到目標代碼中,只是在程序運行時才被載入,因為在程序運行期間還需要動態(tài)庫的存在。

Bundle文件

Bundle文件可以用于存放資源文件,可用于多人合作開發(fā),避免資源重名。里面可以存儲xib文、資源圖片等。Bundle文件是靜態(tài)的,不進行編譯的。所以使用Bundle中的資源,就需要找到相應的資源路徑。另外,我看別人博客上是說,.a文件中是無法用Bundle文件的,只能另存一個文件;Framework靜態(tài)庫可以用Bundle文件;我也沒試過,請試過的小伙伴留言告訴我,我就偷個懶,嘿嘿

總結:同一個靜態(tài)庫在不同程序中使用時,每一個程序中都得導入一次,打包時也被打包進去,形成一個程序。而動態(tài)庫在不同程序中,打包時并沒有被打包進去,只在程序運行使用時,才鏈接載入(如系統(tǒng)的框架如UIKit、Foundation等),所以程序體積會小很多,但是蘋果不讓使用自己的動態(tài)庫,否則審核就無法通過。

一、創(chuàng)建 .a 靜態(tài)庫

1. 新建工程。比如我們的工程名叫PSSTest,那么我們創(chuàng)建的.a靜態(tài)庫的名字最好就是前面加個lib,如libPSSTest.a。

  • 新建工程 (選中xcode,按commond + shift + N)


  • 此時工程目錄是這個樣子,.a文件還沒有被創(chuàng)建,因此是紅色的


  • 你可以把圖中 libPSSTest.h.m 換成你自己要生成庫的文件(可以是多個),在這里我就不換了,就用這兩個文件,我們在.h文件中添加一個方法+sayHello,并在.m中實現(xiàn)它

// 一定要記得在.h中聲明哦
+ (void)sayHello
{
    NSLog(@".a靜態(tài)庫:Hello, world!");
}

2. 添加Headers

  • 按照下圖順序進行操作


這里需要注意的是暴露出來的頭文件中import的其他類也得添加到public中暴露出來。
如果不想將import的類暴露出來,那么在頭文件中用@class 然后在對應的.m文件中再import。
總之
1. 你再外面用到的類,一定要暴露出來;
2. 你暴露出來的類,頭文件中導入的類也一定是暴露出來的
3. 如果提示導入頭文件報錯,找不到文件,找不到誰暴露誰就對了

3. 進行打包前的一些配置

  • 設置編譯模式,打開xcode菜單Product -> Scheme -> Edit Scheme,改成release模式,如下圖


  • 編譯機器的選擇,如下圖,一定要選擇NO。(如果選擇yes,生成部分機型,選擇NO則適配所有機型,想了解更多,請自行百度,總之,選NO就對了)


4. 接下來,我們進行打包

操作簡述:
1. 在真機情況下編譯 (Generic iOS Device),并記錄下.a文件的絕對路徑
2. 在模擬機情況下編譯(隨便吧,別賤嗖嗖的用iPhone4,雖然我也沒試過有沒有問題吧,有興趣可以試試[emj壞笑]),并記錄下.a文件絕對路徑
3. 用命令行合并1、2部記錄的文件,到新的.a文件,名字最好取開始我們取的名字吧,命令行:lipo -create 文件1路徑 文件2路徑 -output 最終文件路徑
4. 把你要暴露的.h文件和你已經生成的.a文件搞到一個文件夾里,這個文件夾就可以直接拖到工程里用啦

4.1 在真機情況下編譯 (Generic iOS Device),并記錄下.a文件的絕對路徑

4.1

4.2 在模擬機情況下編譯,并記錄下.a文件絕對路徑,本操作和上步操作一模一樣,只不過需要選擇一個模擬器,隨便選吧,我是選的iPhone7P,不截圖了

4.3 使用命令行,合并剛剛記錄的兩個路徑,到另一個路徑,例如:

lipo -create /Users/xxxxx/Library/Developer/Xcode/DerivedData/libPSSTest-bmfbhsxiqeajiigltpqjlxhhpjjh/Build/Products/Release-iphoneos/liblibPSSTest.a空格/Users/shanhexia/Library/Developer/Xcode/DerivedData/libPSSTest-bmfbhsxiqeajiigltpqjlxhhpjjh/Build/Products/Release-iphonesimulator/liblibPSSTest.a -output /Users/shanhexia/Desktop/libPSSTest.a

我是把合成之后的.a文件放到桌面上了

4.4 也是最后一步,把我們剛合成的.a文件和想要暴露的.h文件,弄到一個文件夾下
新建一個文件夾,取名libPSSTest,把文件復制粘貼進來,如下圖

4.5 創(chuàng)建.a靜態(tài)庫就已經創(chuàng)建完了,我們來試試吧,導入剛剛4.4創(chuàng)建的文件夾,導入頭文件,調用方法看看有沒有打印

看,我們成功了

4.6 補充:

  1. category是我們實際開發(fā)項目中經常用到的,把category打成靜態(tài)庫是沒有問題的,但是在用這個靜態(tài)庫的工程中,調用category中的方法時會有找不到該方法的運行時錯誤(selector not recognized),解決辦法是:在使用靜態(tài)庫的工程中配置other linker flags的值為-ObjC。
  2. 如果一個靜態(tài)庫很復雜,需要暴露的.h比較多的話,就可以在靜態(tài)庫的內部創(chuàng)建一個.h文件(一般這個.h文件的名字和靜態(tài)庫的名字相同),然后把所有需要暴露出來的.h文件都集中放在這個.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出來就可以了。

二、創(chuàng)建.Framework靜態(tài)庫

1. 新建工程。比如我們的工程名叫PSSFramework

  • 新建工程 (選中xcode,按commond + shift + N)


  • 添加文件到工程,并且在PSSFramework.h文件中導入接口文件

    圖片.png

  • 在PSSObject中添加+sayHello方法,并在.m中實現(xiàn)

// 一定要在`.h`中暴露方法哦
+ (void)sayHello
{
    NSLog(@".framework: Hello, world!");
}

2. 添加Headers

  • 這一步和創(chuàng)建.a的時候一模一樣,請往上翻。不過跟.a不同的是,貌似它里面本來就有Headers了,但是只給你暴露了一個.h文件,需要多暴露的話再自己拖吧

3. 打包前的一些配置

  • 設置編譯模式,打開xcode菜單Product -> Scheme -> Edit Scheme,改成release模式,如下圖(這一步和生成.a一樣,我就借用圖了)

  • 編譯機器的選擇,如下圖,一定要選擇NO。(這一步和生成.a一樣,我就借用圖了)

  • 修改生成的Mach-O格式(很重要)

圖片.png

4. 打包Framework (合并模擬器版framework和真機版framework)

  • 分別在真機(Generic iOS Device)和模擬器編譯,這次不用記錄路徑,一會我會標出合并哪兩個文件
    注意: 合并的命令同上面相似,不同之處是:framework靜態(tài)庫合并的不是framework,而是framework下的一個二進制文件,即下圖中我標出來的文件。
    lipo -create 第一個framework下二進制文件的絕對路徑 第二個framework下二進制文件的絕對路徑 -output 最終的二進制文件路徑。

    圖片.png

    圖片.png
  • 接下來我們進行合并,我們把新合并的二進制文件放到Release-iphoneosRelease-iphonesimulator同一個文件夾下

    命令行如下
    lipo -create /Users/xxxxx/Library/Developer/Xcode/DerivedData/PSSFramework-ehyytcfdvluxetbnmqcfzosxrbtu/Build/Products/Release-iphoneos/PSSFramework.framework/PSSFramework``/Users/shanhexia/Library/Developer/Xcode/DerivedData/PSSFramework-ehyytcfdvluxetbnmqcfzosxrbtu/Build/Products/Release-iphonesimulator/PSSFramework.framework/PSSFramework -output /Users/shanhexia/Library/Developer/Xcode/DerivedData/PSSFramework-ehyytcfdvluxetbnmqcfzosxrbtu/Build/Products/PSSFramework

  • 圖片.png
  • 通過上一步,我們已經把我們要的Framework搞到桌面上了,接下來我們就試試能不能用吧。將Framework拖進工程,導入框架,調用方法,看看有沒有打印

    我試了,確實是能用,不截圖了

三、Bundle文件的使用

1. 創(chuàng)建Bundle

桌面上創(chuàng)建一個文件夾,把文件夾的后綴改為. bundle這時他就變成一個bundle文件了,這時我們右鍵顯示包內容就可以把對應的圖片資源等放進文件中,然后把他丟進工程中就可以使用了。

2. 使用方法 (親測可用)

圖片.png

結束語

實際上,在項目中,我們用別人的Framework.a比較多一些,開發(fā)自己的項目的時候,我倒是沒怎么用到過,但是公司如果希望一部分代碼需要保密,是可以用這種方式的。或者你開發(fā)了一個功能,不想開源,也可以這樣搞。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容