iOS中的動態庫和靜態庫的區別

背景: 阿里的直播framwork是以動態庫的形式提供的,通過溝通,因爲他們使用了遵循LGPL協議的第三方庫,因此只能以動態庫的形式提供;
介紹

iOS中靜態庫的形式:.a .framework iOS中動態庫的形式:.dylib .frameworkhtml

其中系統的.framework是動態庫,本身建立的.framework是靜態庫 將Mach-O Type設爲Static Library,framework能夠是動態庫也能夠是靜態庫,對於系統的framework是動態庫,而用戶製做的framework只能是靜態庫。xcode

iOS8.0之後支持的動態庫架構

靜態庫和動態庫的區別: 靜態庫:連接時完整拷貝到可執行文件中,屢次使用就有多分拷貝 動態庫:連接時不復制,程序運行時由系統動態加載到內存,系統加載一次,多個程序共用app

.a 和 .framework的區別:
  1. .a是純二進制文件, .framework除了二進制文件還包含頭文件和資源文件
  2. .a不能直接使用,須要頭文件(.h)配合;framework可直接使用
  3. .a + .h + source = .framework
  4. Xcode在編譯連接時,對於靜態庫和動態庫的處理方式是有區別的:(此處感謝iOS知識小集最近的總結,解答了我對此處的疑惑,iOS開發能夠關注該公衆號)
  • 對於靜態庫,在連接時,Xcode會自動篩選出靜態庫中的不一樣architecture合併到對應處理器架構的主可執行二進制文件中;而在打包時,Xcode會自動忽略掉靜態庫中未用到的architecture,eg. i38六、x86_64等模擬器架構;
  • 對於動態庫,在編譯打包時,Xcode會直接拷貝整個動態framework文件到最終的ipa包中,只有在App真正運行的時候纔會動態連接。 可是蘋果是不容許最終上傳到App Store Connect後臺的ipa文件包含模擬器架構的,會報Invalid Architectures。
framework中資源訪問方法:

首先,framework中的資源再也不mainbundle中,下面兩種方式均可以訪問其所在bundle:url

//方法1:在framework中的隨便一個類中便可訪問
NSBundle *bundle =  [NSBundle bundleForClass:self.class];
//方法2:在任何地方均可以訪問,其中com.xy.framwork爲framework的CFBundleIdentifier
NSBundle *bundle =  [NSBundle bundleWithIdentifier:@"com.xy.framwork"];

而後就能夠拿這個bundle來訪問資源了操作系統

//訪問圖片
UIImage *image = [UIImage imageNamed:imageName inBundle:bundle compatibleWithTraitCollection:nil];
//訪問文件,使用NSBundle的實例方法獲取文件url或者路徑
NSURL *sourceUrl = [bundle URLForResource:productName withExtension:@".xml" subdirectory:subDir];
NSString *filePath = [bundle pathForResource:productName ofType:@"xml" inDirectory:subDir];
Embedded Binaries 和 Linked Frameworks and Libraries的區別

官方介紹參考連接命令行

  • Linked Frameworks and Libraries: 系統的framwork或者擴展程序中使用主程序中的framwork的時候,不須要把framwork包含到程序的bundle中,使用該模式code

  • 對於靜態庫(.a):該方式會將靜態庫中的代碼拷貝到主程序的ipa包中,ipa包體積也會隨之變大;在運行時不須要再處理依賴關係,全部的事情都在編譯連接階段完成;xml

  • 對於動態庫(.dylib、ystem-supplied framework):會將動態庫放到系統的動態庫存放目錄,這樣就不須要將第三方的外部庫拷貝到主程序的ipa中,而且不一樣的程序均可以找到它使用它,這不只節省了安裝包大小,同時還節省了內存佔用。htm

  • 當使用一個第三方的framwork(下載的或者本身生成的),它們並不會被放到操做系統上,在這種狀況下,僅僅linked這個庫就不行了,還須要在"Copy Frameworks" 時期把它嵌入到應用的ipa包裏面,這樣,在程序運行的時候,發如今系統動態庫目錄下找不到這個庫,就能在應用程序包裏面找到並使用它。

embed到應用中的動態庫,就像是圖片、音頻等資源文件同樣,只不過它是一個可執行文件,在運行時採起加載執行。

  • Embedded Binaries: Embed是把這個庫嵌入到最終輸出的程序的bundle裏面。 若是是第三方的動態庫(別人提供或者本身生成),就須要對該庫進行embed
動態庫包含動態庫的問題:

一個動態庫A.framework包含了另一個動態庫B.framework,而後將A提供給主工程使用;這種狀況下,若是隻提供了A給主工程,那麼會在運行時報 image not found 的錯誤,查看了蘋果文檔, 發如今iOS開發中不支持這種作法,必須在主工程中同時embedA和B才能正常運行

#####如何區分一個framwork是靜態庫仍是動態庫:

命令行進入動態庫文件,使用file命令能夠看到區別,分別以騰訊分享framwork(靜態)和阿里直播framwork(動態)爲例展現:

cd TencentOpenAPI.framework
file TencentOpenAPI

輸出

TencentOpenAPI: Mach-O universal binary with 4 architectures: [arm_v7:current ar archive] [arm64]
TencentOpenAPI (for architecture armv7):	current ar archive
TencentOpenAPI (for architecture i386):	current ar archive
TencentOpenAPI (for architecture x86_64):	current ar archive
TencentOpenAPI (for architecture arm64):	current ar archive

archive代表這是一個靜態庫

cd AliyunPlayerSDK.framework
file AliyunPlayerSDK

輸出

AliyunPlayerSDK: Mach-O universal binary with 4 architectures: [i386:Mach-O dynamically linked shared library i386] [arm64]
AliyunPlayerSDK (for architecture i386):	Mach-O dynamically linked shared library i386
AliyunPlayerSDK (for architecture x86_64):	Mach-O 64-bit dynamically linked shared library x86_64
AliyunPlayerSDK (for architecture armv7):	Mach-O dynamically linked shared library arm_v7
AliyunPlayerSDK (for architecture arm64):	Mach-O 64-bit dynamically linked shared library arm64

dynamically linked shared library代表這是一個動態庫

相關文章
相關標籤/搜索