參考文章:- http://my.oschina.net/leejan97/blog/284193
- https://blog.csdn.net/jingcheng345413/article/details/54969324
- http://www.reibang.com/p/a04310199d7b
- http://www.cocoachina.com/articles/23082
一推汽、共同點(diǎn):
兩者其實(shí)都是靜態(tài)庫烂叔。
二边坤、區(qū)別
1.承載的內(nèi)容范疇:
(1)Static Library的產(chǎn)出物只是一個(gè).a文件,為二進(jìn)制執(zhí)行文件赋元。分享給別人的時(shí)候,頭文件寥掐、靜態(tài)資源文件需要另外提供蛔六。
(2)Framework為一站式分享方案,其實(shí)是一個(gè)文件夾朝捆,其中包含代碼簽名般渡、頭文件、二進(jìn)制執(zhí)行文件芙盘、靜態(tài)資源文件等驯用。
2.頭文件搜索路徑的區(qū)別:StaticLibrary需要設(shè)置頭文件搜索路徑,F(xiàn)ramework不需要儒老。
3.當(dāng)存在對外部代碼庫依賴的時(shí)候
(1)StaticLibrary:能夠只引用外部庫的頭文件蝴乔,調(diào)用外部庫的公開方法,而不引入其庫實(shí)現(xiàn)驮樊,實(shí)現(xiàn)與引用庫的分離部署薇正。
(2)Framework:要引用一個(gè)外部庫片酝,就必須要將此外部庫的實(shí)現(xiàn)放入Framework內(nèi)編譯才可以。如果要想達(dá)到StaticLibrary的效果挖腰,可以使用運(yùn)行時(shí)方式調(diào)用雕沿。
4.運(yùn)行環(huán)境(對3的理解升級)
(1)StaticLibrary:共享其運(yùn)行環(huán)境,假如其運(yùn)行環(huán)境中包換庫中同一個(gè)類猴仑,會發(fā)生代碼沖突审轮,必須剝離其中一方的此類,然后共享此類宁脊。
(2)Framework:與其運(yùn)行環(huán)境隔離断国,假如其運(yùn)行環(huán)境中包換庫中同一個(gè)類,不會發(fā)生沖突榆苞,同名的兩個(gè)類會在各自的環(huán)境中獨(dú)立運(yùn)行,互不干擾霞捡,哪怕是單例類坐漏。
綜合,如何選擇使用Framework還是StaticLibrary
(1)假如不想在同一個(gè)App中包含多份三方庫(減小包大小)碧信,可以使用StaticLibrary赊琳,庫本身和App共享第三方庫。但是產(chǎn)出物的結(jié)構(gòu)可能會比較亂砰碴。
(2)假如不想考慮和App的代碼沖突問題躏筏,庫本身獨(dú)立使用需要的庫,想提供比較好的庫結(jié)構(gòu)呈枉,可以使用Framework趁尼。但是假如庫本身和App都使用了同一個(gè)三方庫,會存在兩份三方庫猖辫,會增加包大小酥泞。
三、創(chuàng)建Static Library
1啃憎、創(chuàng)建Static Library芝囤,點(diǎn)擊File--> New --> Target(如圖)
2.創(chuàng)建了靜態(tài)庫Static Library之后,Xcode自動(dòng)為我們創(chuàng)建了XXX.h/.m文件
3.編譯項(xiàng)目辛萍,生成對應(yīng)的靜態(tài)庫.a文件悯姊,編譯的時(shí)候,記得選上項(xiàng)目(當(dāng)然你的是什么名字的贩毕,就選對應(yīng)的就好)悯许,然后用模擬器環(huán)境和真機(jī)環(huán)境都編譯一下,紅色的libXXXX.a文件就變成黑色了
4耳幢、合并靜態(tài)庫
針對真機(jī)和模擬器的靜態(tài)庫文件只能在一個(gè)平臺下面使用岸晦,好在我們可以將真機(jī)和模擬器上面的靜態(tài)庫文件合并成一個(gè)在真機(jī)和模擬器都可以使用的靜態(tài)庫文件欧啤,通過在終端輸入命令即可完成該目的,
完整的命令:
lipo -create /Users/doudou/Library/Developer/Xcode/vedData/JJPickView-eqviycrqcwweiretrodyzdijhulx/Build/Products/Debug-iphoneos/libXXX.a /Users/doudou/Library/Developer/Xcode/DerivedData/JJPickView-eqviycrqcwweiretrodyzdijhulx/Build/Products/Debug-iphonesimulator/libXXX.a -output /Users/doudou/Desktop/libXXX.a
這個(gè)是自己的文件路徑启上,改成自己相應(yīng)的路徑
5邢隧、使用靜態(tài)庫文件
這時(shí)候我們就可以使用自己創(chuàng)建、編譯生成的靜態(tài)庫文件了冈在,將相關(guān)xxx.h文件和桌面上面的libXXX.a文件拖到想要使用的項(xiàng)目中
四倒慧、創(chuàng)建framework
打開Xcode,新建工程包券。
選擇 create framework & library
選擇 framework創(chuàng)建我們所需要的文件類,比如繼承與NSobject 的testH 類
更改參數(shù)
接下來對我們的這個(gè).framework靜態(tài)庫進(jìn)行一些簡單的設(shè)置纫谅。
(1)首先是Dead Code Stripping設(shè)置為NO,網(wǎng)上對此項(xiàng)的解釋如下溅固,大致意思是如果開啟此項(xiàng)就會對代碼中的”dead”付秕、”unreachable”的代碼過濾,不過這個(gè)開關(guān)是否關(guān)閉侍郭,似乎沒有多大影響询吴,不過為了完整還原framework中的代碼,將此項(xiàng)關(guān)閉也未曾不可亮元。
(2)然后將Link With Standard Libraries關(guān)閉猛计,我想可能是為了避免重復(fù)鏈接
(3)最后將Mach-O Type設(shè)為Static Library,framework可以是動(dòng)態(tài)庫也可以是靜態(tài)庫爆捞,對于系統(tǒng)的framework是動(dòng)態(tài)庫奉瘤,而用戶制作的framework只能是靜態(tài)庫。
(4)還要記得把要公開的類添加到我們的FrameWorkTest.h中
- 打包 Framework
使用 lipo 命令
- 首先要支持多個(gè)架構(gòu)煮甥,設(shè)置路徑 Build Settings -> Build Active -> NO 支持多個(gè)架構(gòu)的靜態(tài)庫盗温。然后選擇模擬器和Build Only Device,分別編譯一次苛秕。
2.通過終端命令將兩個(gè)framework合為一個(gè)模擬器和真機(jī)都可使用的framework肌访。
lipo -create /Users/chenjiazhen/Library/Developer/Xcode/DerivedData/CharTest-dxlrsuvcbsfyohedbbfitrvbqygx/Build/Products/Debug-iphoneos/CharTest.framework/CharTest /Users/chenjiazhen/Library/Developer/Xcode/DerivedData/CharTest-dxlrsuvcbsfyohedbbfitrvbqygx/Build/Products/Debug-iphonesimulator/CharTest.framework/CharTest -output /Users/chenjiazhen/Desktop/CharTest
然后 會生成一個(gè).lipo文件
此時(shí) 修改后綴.framework 即可生成我們需要的framework包
最后需要總結(jié)的:
1、在制作framework或者lib的時(shí)候艇劫,如果使用了category吼驶,則使用改FMWK的程序運(yùn)行時(shí)會crash,此時(shí)需要在該工程中 other linker flags添加兩個(gè)參數(shù) -ObjC -all_load店煞。(這點(diǎn)沒有親測)
2蟹演、帶有圖片資源的需要把圖片打包成Bundle文件,和framework一起拷貝到相應(yīng)的項(xiàng)目中顷蟀。
3酒请、公開的類中如果引用的private的類,打包以后對外會報(bào)錯(cuò)鸣个,找不到那個(gè)private的類羞反,可以把那個(gè)private的.h放到(也沒親測)
4布朦、namespace 沖突。靜態(tài)庫用了某第三方庫昼窗,項(xiàng)目也用了同樣的第三方庫是趴,在編譯的時(shí)候就會有 duplicate symbol 錯(cuò)誤,因?yàn)橛袃煞萃瑯拥牡谌綆斐尉=鉀Q辦法就是把用到的第三方庫加上自定義前綴唆途,包括類名、delegate 協(xié)議掸驱、常量名肛搬,尤其需要注意 Category 的方法名要修改。