iOS中的靜態庫和動態庫
概念
靜態庫(Static Library)
以 .a 為后綴,它是你的源碼的實現.m文件編譯而成的二進制文件集合,需要配合上暴漏的.h文件使用,它在引用鏈接時拷貝至可執行文件中,程序運行時加載到內存,期間被多次使用就有多份冗余拷貝和加載;
動態庫(Dynamic Framework)
以.dylib和.framework為后綴,也是一堆.h和.m的集合,.m同樣被編譯成了二進制,不同的是,它還可以包含nib文件,資源文件等,系統的framework在鏈接時先檢查內存中是否已經加載,如果有,就不再進行復制,這樣多個應用程序可以共享內存中得同一份庫文件,節省了內存.
注意:
1.在iOS8之前,或者xcode6之前,你可能也見過開發者自己打包的framework,具體方法可以看這里和這里,但是,這些辛苦打包出來的framework依然是靜態庫的形式(程序運行時被加載到內存,即便此時內存中其他應用也用了此framework並且已經加載進內存了);
2.系統的.framework是動態庫,也就是說我們代碼中最常見的#import <Foundation/Foundation.h>
導入的foundation框架,當我們運行程序的時候,其實內存中已經預加載了這些系統框架,此時我們打開應用時不會再次加載這些,這就減少了內存的占用.雖然在xcode6之后蘋果爸爸允許我們自己生成framework了,但是,它依然只是存在於當前應用的沙盒中而非提交到系統中,這就意味着每次依然會加載到內存中...
創建自己的framework
相比較於靜態庫,動態庫有着自己的優勢,除去上文中說道的資源包含和內存加載問題,在使用的時候相比較於.a的靜態庫也更方便,因為它本省包含了我們所需要的所有資源(自包含);所以我建議,我們更應該生成動態framework而非.a靜態庫;
為已有類擴展分類使我們經常的做法,現在我們將實例如何將分類打包成framework使用;
1.新建工程->選擇iOS下Framework&Library->CocoaTouch Framework;
2.將我們的要打包的文件拖進工程,這里不要建立文件夾(圖1);
可以看到這里有一個額外的文件XCommonExtension.h,它在我們生成工程之后自動為我們生成,這里你可以將打包的public文件都通過import的方式導入頭文件到這里,在其他開發者使用framework的時候只用引用這個.h頭文件即可;
3.在build phases中,我們可以看到有一個Headers的選項,我們上一步添加的文件都會在這里顯示,不過默認的是在project下,這里我們需要把需要暴露的拖動到public下,完成后如下(圖2)
4.Build-Run,到此,你的""模擬器版""的framework已經生成了,它只能在模擬器中鏈接引用,到真機運行的時候就有問題了,接下來,我們在生成真機版的framework,同時把他們合並成一個通用的framework;
5.選中target->在工具欄點擊Editor->Add Target->在彈出的選擇框中選擇Other->Aggregate->Next;現在你的工程總有了兩個target(圖3)
6.選中剛加入的這個target,點擊右上的 + 號 -> New Run Script Phase,我們將在這里嵌入我們的腳本script;
嵌入以下腳本:
# Sets the target folders and the final framework product. # 如果工程名稱和Framework的Target名稱不一樣的話,要自定義FMKNAME # 例如: FMK_NAME = "MyFramework" FMK_NAME=${PROJECT_NAME} # Install dir will be the final output to the framework. # The following line create it in the root folder of the current project. INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework # Working dir will be deleted after the framework creation. WRK_DIR=build DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework # -configuration ${CONFIGURATION} # Clean and Building both architectures. xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build # Cleaning the oldest. if [ -d "${INSTALL_DIR}" ] then rm -rf "${INSTALL_DIR}" fi mkdir -p "${INSTALL_DIR}" cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/" cp -R "${SIMULATOR_DIR}/" "${INSTALL_DIR}/" # Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product. lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}" rm -r "${WRK_DIR}" open "${INSTALL_DIR}"
7.選中新加入的這個Scheme,編譯運行(圖4);
8.編譯運行之后你的finder就會彈出生成的framework,找到並拷貝出來,大功告成,下面我們就可以使用它了;
使用我們的framework
9.在新建的工程中加入我們生成的framework,在Embedded Framework中加入我們的framework,在要使用的文件中引入頭文件;
import <XCommonExtension/XCommonExtension.h>
注意:
1.這里我們打包的為分類,在使用的時候,需要在other linker flag中添加-ObjC或者-force_load參數;
2.帶有圖片資源的需要把圖片打包成Bundle文件,和framework一起拷貝到相應的項目中.
到此為止,我們制作出來了可供使用的framework,如果想要更多人使用到你的framework,你可以利用cocoaPods,編寫自己的PodSpec文件,或者利用Carthage,發布你的framework;
可能導入會存在問題,這里我就一直報錯沒有這個庫文件,可很多方法都試了還是報錯.(遺留問題吧!!!)不過framework還是打包成功的.
有知道的可以郵件聯系我喲!!