靜態庫 VS 動態庫
靜態庫:靜態庫在Objective-C裡面以.a或者.framework作為後綴,目前開發者自己創建的庫文件(Framework)其實都是以靜態庫的形式鏈接到執行文件的。鏈接時完整的拷貝到了可執行文件中,被多次使用就會有多份拷貝(eg:iOS8+的Extention中使用)。靜態庫文件一般都會比較大,因為所有要使用的數據都會被編譯進去,而且如果庫文件的某個函數改變了,那麼就又需要重新編譯新的庫文件了,優點就是編譯後的執行程序不需要外部的函數庫支持,因為所有的函數都已經被編譯進去了。
動態庫:動態庫在Objective-C裡面以dylib或者.framework最為後綴,系統為我們提供的framework就是動態庫,目前開發者是不允許使用動態庫的,因為我們自己創建的庫文件雖然buildSetting中的Mach-O Type設置為Dynamic Library,但是使用時直接鏈接到程序裡面的,而不是放在服務器上進行更新,開發者如果使用動態庫放在服務器上,然後動態的加載dlopen是不會通過審核的,不然Apple的審核就沒有意義了。動態庫在鏈接時不復制,程序運行時由系統動態加載到內存,系統只加載一次,多個程序間共用,節省內存,而且升級方便。
我們創建framework庫文件時,系統默認是動態庫的格式,如果想做成靜態庫,需要在buildSetting中將Mach-O Type選項設置為Static Library就行了!
framework VS .a
a:.a是純二進制文件,不能直接拿來使用,需要配合頭文件、資源文件一起使用。代碼資源、圖片、json資源、xib文件等是無法打包進去的,所以使用.a靜態庫的時候需要三個組成部分:.a文件+開放的頭文件+資源文件。
framework:相當於一個文件夾,可以直接拿來使用,所需要的資源、頭文件、源文件都在裡面。
Static Library/Framework VS Embedded Framework
Embedded Framework是iOS8引入的為了方便Extention和宿主APP公用一份代碼庫而引入的,Embedded Framework必須是Dynamic framework(在buildSeting中設置為Dynamic)。如果你想限制在Extention中不可用的API放入你的Embedded Framework,你可以勾選Allow app extension API only選框。
-framework的妙用
有些靜態庫文件我們只是在DEBUG模式下,調試使用。而不想打入release包中,因為這樣會增加安裝包的大小,這時可以在buildSetting中的Other Linker Flags下對應的模式中添加需要的庫文件,以-framework標記,這樣程序編譯的時候就會根據裡面的標記來編譯進執行文件中。
在使用時可以利用runtime的反射來判斷庫文件有沒有被加載,或者利用buildSetting中的預編譯宏Preprocessor Macros來標記。
if (NSClassFromString(@"MyFramework") != Nil) { //MyFramework被加載了 } //or #if DEBUG /*該模式下可使用DEBUG模式下‘Other Linker Flags’ 通過‘-framework’引入的靜態庫*/ #endif
參考文章
https://hacking-ios.cocoagarage.com/working-with-a-static-library-framework-vs-embedded-framework-9ca7cd77b4f9#.ign0m484w
http://www.knowstack.com/framework-vs-library-cocoa-ios/
http://stackoverflow.com/questions/27015154/link-binary-with-libraries-vs-embed-frameworks