iOS靜態庫 【.a 和framework解析】【超詳細】,ios.a

來源:互聯網
上載者:User

iOS靜態庫 【.a 和framework解析】【超詳細】,ios.a
一、什麼是庫?

庫是共用程式碼的方式。

庫從本質上來說是一種可執行代碼的二進位格式,可以被載入記憶體中執行。庫分靜態庫和動態庫兩種。
iOS中的靜態庫有 .a 和 .framework兩種形式;動態庫有.dylib 和 .framework 形式,後來.dylib動態庫又被蘋果替換成.tbd的形式。

二、靜態庫與動態庫的區別?

靜態庫: 連結時完整地拷貝至可執行檔中,被多次使用就有多份冗餘拷貝。

動態庫: 連結時不複製,程式運行時由系統動態載入到記憶體,供程式調用,系統只載入一次,多個程式共用,節省記憶體。[ios暫時只允許使用系統動態庫];

靜態庫和動態庫是相對編譯期和運行期的:靜態庫在程式編譯時間會被連結到目標代碼中,程式運行時將不再需要改靜態庫;而動態庫在程式編譯時間並不會被連結到目標代碼中,只是在程式運行時才被載入,因為在程式運行期間還需要動態庫的存在。
總結:同一個靜態庫在不同程式中使用時,每一個程式中都得匯入一次,打包時也被打包進去,形成一個程式。而動態庫在不同程式中,打包時並沒有被打包進去,只在程式運行使用時,才連結載入(如系統的架構如UIKit、Foundation等),所以程式體積會小很多,但是蘋果不讓使用自己的動態庫,否則審核就無法通過。

三、iOS裡靜態庫形式?

.a和.framework

四、iOS裡動態庫形式?

.dylib和.framework

五、framework為什麼既是靜態庫又是動態庫?

系統的.framework是動態庫,我們自己建立的.framework是靜態庫。

六、a與.framework有什麼區別?

.a是一個純二進位檔案,.framework中除了有二進位檔案之外還有資源檔。

.a檔案不能直接使用,至少要有.h檔案配合,.framework檔案可以直接使用。

.a + .h + sourceFile = .framework。

建議用.framework.

七、為什麼要使用靜態庫?

方便共用代碼,便於合理使用。

實現iOS程式的模組化。可以把固定的業務模組化成靜態庫。

和別人分享你的程式碼程式庫,但不想讓別人看到你代碼的實現。

開發第三方sdk的需要。

八、製作靜態庫時的幾點注意:

1注意理解:無論是.a靜態庫還.framework靜態庫,我們需要的都是二進位檔案+.h+其它資源檔的形式,不同的是,.a本身就是二進位檔案,需要我們自己配上.h和其它檔案才能使用,而.framework本身已經包含了.h和其它檔案,可以直接使用。

2圖片資源的處理:兩種靜態庫,一般都是把圖片檔案單獨的放在一個.bundle檔案中,一般.bundle的名字和.a或.framework的名字相同。.bundle檔案很好弄,建立一個檔案夾,把它改名為.bundle就可以了,右鍵,顯示包內容可以向其中添加圖片資源。

3category是我們實際開發項目中經常用到的,把category打成靜態庫是沒有問題的,但是在用這個靜態庫的工程中,調用category中的方法時會有找不到該方法的執行階段錯誤(selector not recognized),解決辦法是:在使用靜態庫的工程中配置other linker flags的值為-ObjC。

4如果一個靜態庫很複雜,需要暴露的.h比較多的話,就可以在靜態庫的內部建立一個.h檔案(一般這個.h檔案的名字和靜態庫的名字相同),然後把所有需要暴露出來的.h檔案都集中放在這個.h檔案中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出來就可以了。

九、建立.a靜態庫

第一步,建立工程。一般使用工程名就使用庫的名稱,比如我這裡用LIB來建立靜態庫,我的工程名就取名為LIB,建立的.a靜態庫就是LIB.a。

第二步,刪除.m檔案,保留.h檔案, 一般靜態庫都有一個總的.h檔案,方便外部匯入標頭檔。然後匯入需要打包的源檔案。

第三步,先用真機,編譯一次,再用模擬器編譯一次。就可以產生.a檔案(必須先用真機要不然,不能產生)。

第四步,Xcode產生的.a檔案預設沒有匯出.h檔案。需要自己添加。

第五步,匯出Products靜態庫的配置(其實不用設定此步驟,如果真機編譯的話,產生匯出的時候系統預設會變成Releasse[但是模擬器不會(如果不改這裡 得需要把Debug設定為NO)])

注意:如果第五步中,不將Build Configuration改為Release,則打包出來的靜態庫會存於【Debug-iphoneos】和【Debug-iphonesimulator】兩個檔案夾下。
我們一般都使用Release模式,因為程式最終發布之後是Release版的,所以靜態庫也是在Release模式下使用。

第六步,合成模擬器的架構【預設:模擬器編譯只會產生對應的1種架構,真機編譯會合成兩種架構】

如果第六步這裡,設定為YES,那麼編譯出來的.a靜態庫就只包含當前裝置的架構。


舉個例子:如果我們選擇iPhone 5模擬器【Command+B】編譯,則編譯出來的.a靜態庫只能用iPhone4s~5模擬器跑程式, 用iPhone5s~6plus,則會報找不到x86_64的libFMDB庫。

設定為 NO 之後,【Command+B】不管選擇哪個【模擬器】,則都會把【386 : 32位架構 4S ~ 5】【x86_64 : 64位架構 5S ~ 現在的機型】的架構都打包合并。

【注】【真機】不設定[Build Active Architecture Only]也預設會自動合并的armv7 和amr64架構 。但是armv7s架構被蘋果放棄了,真機要想合并armv7s的話需要進行如下操作再編譯。(其實沒必要設定這個)

第七步,合并架構【真機和模擬器】

真機和模擬器合并: lipo -create 靜態庫1.a(路徑) 靜態庫2.a(路徑)-output 新靜態庫.a

第八步,資源套件的問題

1. 靜態庫的資源, 都應該放到尾碼為.bundle的檔案夾中 --> 避免檔案與本地檔案重名被覆蓋, 導致載入資源檔出錯【註:要載入bundel路徑】

2. 靜態庫打包時, 並不會打包資源檔 --> 需要手動拖出去

一. 經典報錯:

找不到符號在XX架構上

Undefined symbols for architecture x86_64(armv7/armv7s/amr64/i386)

二. 架構的分類

1、模擬器架構: 2種

i386 : 32位架構 4S ~ 5

x86_64 : 64位架構 5S ~現在的機型

2、真機架構: 3種

armv7 : 32位架構 3GS ~ 4S

armv7s: 特殊的架構 5 ~ 5C (此架構有問題, 有的程式變得更快, 有的程式變得更慢)

amr64 : 64位架構 5S ~現在的機型

64位/32位: 記憶體定址不同

三. 如何查看靜態庫架構

找到Products檔案夾, 如果.a檔案是黑色, 右鍵開啟 到Products檔案夾

終端中lipo -info

Generic iOS Device編譯出來的OS可用, 有2種架構:armv7/ arm64 (不包含armv7s: 特殊的架構)

iPhone6S模擬器編譯出來的: x86_64

iPhone4S模擬器編譯出來的: i386

(不設定Build Active Architecture Only的情況下真機編譯2種架構, 模擬器編譯:對應的1種架構)

四. 合成架構

一般來說, 只需要前兩步即可

1. 模擬器架構的合成: Target --> Build Settings --> Build Active Architecture Only(是否只編譯當前架構) --> Debug 改為NO(改為NO, 模擬器就可以直接合成2種架構)

2. 真機和模擬器合并: lipo -create 靜態庫1.a 靜態庫2.a -output 新靜態庫.a

3.* armv7s這個架構, 在2014年10月份的xcode版本更新中, 取消了預設匯出此架構. 可以不用支援此架構.

如果要支援, 需要手動添加3個架構.

五. Debug和Release版本

一般來說, 我們應該發布的是release版本.

debug:調試版本, 系統本身也會有一些調試代碼. 此版本體積會稍大, 運行會稍慢

release: 發布版本, 系統會去除調試代碼, 體積變小, 運行速度變快. 對使用者來說沒有明顯的感覺

六. 到底要不要合成多個架構

真機和模擬器合成的好處: 調試會非常方便, 缺點是體積會變大(一種架構就佔用一部分體積).

真機和模擬器不合成的好處:體積小, 缺點是調試稍顯麻煩.

七. 資源套件的問題

1. 靜態庫的資源, 都應該放到尾碼為.bundle的檔案夾中 --> 避免檔案重名被覆蓋, 導致載入資源檔出錯

2. 靜態庫打包時, 並不會打包資源檔 --> 需要手動拖出去

十、建立framework靜態庫

第一步、建立工程。一般使用工程名就使用庫的名稱

第二步、匯入需要打包的資源檔,同時把資源檔需要外界訪問的.h檔案匯入到系統推薦的.h中

第三步、真機,模擬器編譯一下。可能會需要輸入AppleID 。匯出的檔案沒有包含.h

第四步、匯出.h

第五步、可以查看一下 沒合并模擬器架構之前包含幾個同.a(可跳過此步)(真機包含兩個,模擬器包含一個)

第六步、合成架構【同.a五六步詳細看上邊】

第七步,合并架構【真機和模擬器】【注意 合并之後的動態/靜態庫要與原來的名稱一致。不然用的時候編譯報錯】

第八步、動態庫變靜態庫【預設是動態】好處是將來使用時不需要設定添加動態庫(也就是下邊的方法)

最後步、

Framework製作後,預設是動態庫.使用時,需要設定一下: Tarteg --> General --> Embedded Binaries -->需要添加對應的動態庫 【注意 要是製作的時候更改為靜態庫的話,就不用執行此方法】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.