Framework 動態(tài)庫 & 靜態(tài)庫

關于 動態(tài)庫 & 靜態(tài)庫 ,參考下面文章:
iOS開發(fā)關于"框架"的那些事
iOS 靜態(tài)庫总珠,動態(tài)庫與 Framework
framework中關于資源的讀取
一篇較為詳細的 iOS動態(tài)靜態(tài)庫創(chuàng)建打包方法 總結


下面這段很有意思办绝,對我有很大啟發(fā),就貼了過來

  • 以前的.a靜態(tài)庫是不能包含資源文件的姚淆。所以毫無疑問孕蝉,如果需要xib, img等資源文件的話,需要打包在.bundle中腌逢,和.a一起發(fā)布降淮,一般保持兩者同樣的名字。

  • 從iOS8開始搏讶,可以用framework佳鳖,并且可以包含資源文件,可以放棄.bundle文件了媒惕。這主要是從使用方便的角度來講的系吩。將代碼和資源分離,完成同一功能要找兩個地方妒蔚,自找麻煩穿挨。

  • 在framework中開發(fā)月弛,就像跟主程序中開發(fā)一樣,按照功能分模塊科盛,劃分文件夾帽衙。將同一功能的文件都放在一個文件夾中,包括Storyboard贞绵,xib厉萝,image,Code等等榨崩,以最短路徑獲取所需要的信息谴垫。

  • 將framework和bundle分兩個隔離是不合理的,同樣母蛛,在framework中包含一個bundle同樣也是不合理的弹渔。模塊間隔離的單位是framework,在framework內部溯祸,應該考慮充分共享以及獲取的方便性肢专,再引入第二級的bundle,只能是自我設限焦辅,得不償失博杖。讓.bundle和.a成為歷史,全面使用framework筷登。

  • 還有一種情況剃根,就是當資源的體積很大的時候,比如視頻前方、地圖之類的狈醉。這種時候,將資源單獨放在一個bundle中惠险,與程序分離苗傅,可以不同時間發(fā)布,也不用重新發(fā)版本班巩,有一定的意義渣慕。不過,對于大資源抱慌,直接以文件的形式下載就可以了逊桦,有必要用bundle多包一層嗎?

  • 除了主程序抑进,其他framework的地位都是平等的强经,不存在framework之中包含framework的概念。取而代之的寺渗,是依賴關系匿情。所以兰迫,整體架構在物理上就兩層,主程序和framework码秉。邏輯上的層次和包含等概念,都要理解依賴鸡号。比如要開發(fā)一個Network.framwork转砖,需要用到AFNetworking.framework。在邏輯上是主程序 -> Network.framwork -> AFNetworking.framework鲸伴。但是在物理上的關系是
    主程序 -> Network.framwork和主程序 ->AFNetworking.framework府蔗。AFNetworking.framework與Network.framwork地位是完全平等的,只不過想用Network.framwork的程序必須同時將AFNetworking.framework包含進來汞窗。
    可以把framework想象為主程序中的一個文件夾姓赤。在沒有framework的主程序中,資源是直接放在根目錄下的仲吏。但是不铆,引入了framework之后,就像把資源移動了相應的子目錄裹唆。這樣路徑就發(fā)生了變化誓斥,NSBundle這個類就是為了區(qū)分這種變化。

  • 動態(tài)庫引用靜態(tài)庫就相當于將代碼直接添加在了動態(tài)庫里

  • 動態(tài)庫不會被打包進動態(tài)庫/靜態(tài)庫中许帐,它只會創(chuàng)建一個引用劳坑,需要在項目中手動添加被引用的動態(tài)庫并在工程的 Embedded Binaries 中添加所需的動態(tài)庫

  • 靜態(tài)庫無法嵌入靜態(tài)庫中。動態(tài)庫確實是把靜態(tài)庫打在了自己的庫中成畦,但是靜態(tài)庫無法做到這一點

framework資源文件讀取

1距芬、在framework里面讀framwork自己的資源文件

這是framework內部的資源,跟其他都沒有關系循帐。但是framework不能單獨存在框仔,必須要放在某個“主程序”中才能起作用。bundle參數(shù)如果不傳拄养,那么默認是mainBundle存和,這種情況路徑就不對了。這種情況下衷旅,可以用下面這個API來獲得bundle參數(shù)捐腿。

 // 獲取bundle參數(shù)

    NSBundle *bundle = [NSBundle bundleForClass:self.class];

    // 讀UIStoryboard

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@“StoryboardName” bundle:bundle];

    // 讀UIImage

    UIImage *image = [UIImage imageNamed:@"icon_back_gray" inBundle:bundle compatibleWithTraitCollection:nil];

    // 文件路徑

    NSString* htmlPath = [bundle pathForResource:@"index" ofType:@"html"];
2、在主程序中讀framework里面的資源文件

同樣也是利用bundle參數(shù)來讀取柿顶,class選擇framework中某個導出的class就可以了茄袖。

// 獲取bundle參數(shù),ZAFinanceFrameworkManager是framework中接口類

    NSBundle *bundle = [NSBundle bundleForClass:[ZAFinanceFrameworkManager class]];
3嘁锯、在framework中讀主程序的資源文件

這個和在主程序中讀自己的一樣宪祥,不需要bundle參數(shù)聂薪,一定要傳的話,就傳nil或者[NSBundle mainBundle]

4蝗羊、從framework里面讀其他framwork里面的資源文件

同樣也是利用bundle參數(shù)來讀取藏澳,class選擇目標framework中某個導出的class就可以了。

在單體程序中耀找,NSBundle這個參數(shù)不需要管翔悠,全部傳nil或者是默認的[NSBundle mainBundle]就可以了。
引入了framework之后野芒,就需要NSBundle這個參數(shù)來區(qū)分資源所在的模塊蓄愁。確定NSBundle比較簡單的方法是用下面這個API,其中的class只要選擇資源所在的framework中的某個class就可以了狞悲。獲取到bundle后撮抓,通過bundle獲取資源文件用法一致。

下面是關于 bundleForClass
https://developer.apple.com/documentation/foundation/nsbundle/1417717-bundleforclass?preferredLanguage=occ
The NSBundle object that dynamically loaded aClass (a loadable bundle), the NSBundle object for the framework in which aClass is defined, or the main bundle object if aClass was not dynamically loaded or is not defined in a framework.
This method creates and returns a new NSBundle object if there is no existing bundle associated with aClass. Otherwise, the existing instance is returned.

+ (NSBundle *)bundleForClass:(Class)aClass;

如何創(chuàng)建 .framework

1摇锋、我們先創(chuàng)建一個名為 LovelyCat 的項目

2丹拯、在創(chuàng)建一個 LovelyCat 的ViewController ,勾選 Also create XIB file

3荸恕、我們往項目中加 加入圖片資源文件(可以是文件夾形式也可以是 .xcassets 形式)咽笼,這里我們項目中加載的是 Resource 文件夾

3、我們可以在 LovelyCat.xib 上放張圖片戚炫,并給圖片加一個點擊事件剑刑,



4、我們來測試一下双肤,由 rootViewController 模態(tài)推出 LovelyCat施掏,完美

5、接下來我們創(chuàng)建一個 Cat target


6茅糜、接下來我們要把 framework 需要的代碼合資源加入 Cat target七芭,如下圖,這里我們把 LovelyCat.h LovelyCat.m LovelyCat.xib 和圖片資源都勾選



7蔑赘、下面我們開始 配置 Cat target 和 外部引用頭文件
我們要把 暴露的 .h 文件拖到 Public 下狸驳,而且在 Cat target 的 Cat.h 中加入 #import <Cat/LovelyCat.h>

8、關于 framework 所支持的指令集缩赛,我們最后單開一個模塊來講耙箍。
下面是 Xcode 中指令集相關選項,我們可以先把 Build Active Architecture Only 設為 NO酥馍。因為我們一直在用模擬器運行辩昆,所以其他的可以先不管

9、這里先說 Linking 中需要設置的選項旨袒。
  • Dead Code Stripping 剝離無用的代碼汁针,我們這里默認就好, 默認 YES(一般對Debug關閉术辐,對Release版本開啟以去除無效路徑僵尸代碼,壓縮安裝包體積)
  • Link With Standard Libraries 用標準庫連接施无,默認就好(如果 YES辉词,那么編譯器在鏈接過程中會自動使用通過標準庫的鏈接器)
  • Mach-O Type 可執(zhí)行文件 類型 默認 Dynamic Library ,我們默認就好 原因看這里iOS開發(fā)關于"框架"的那些事
    其他的默認就好,遇到坑了再來填

    10猾骡、現(xiàn)在我們可以編譯了
    選擇個模擬器瑞躺,真機選擇 Generic iOS Device,因為編譯指令集不同所以編譯后的framework 不能通用

    編譯后卓练,我們可以在 Products 找到我們 Cat.framework ,現(xiàn)在我們可以把他放進其他工程中測試了隘蝎, 我們新建一個 HelloKitty 的工程购啄,把 Cat.framework 拖入 工程中襟企,編譯運行 咦,閃退了...
    不著急 我們把 Cat.framework 加入Embeded Binaries 下狮含,編譯運行 運行 Ok了顽悼,調用Cat.framework 也OK
備注:
  • 如果你用了Category,別人在用你的framework時會發(fā)生崩潰几迄。這時在引用時需要在工程中other linker flags中添加-objC如果依然有問題蔚龙,再添加-all_load。
    不過映胁,我測試了下在 .framework 是動態(tài)庫 添加 Category木羹,并暴露 Category 的頭文件,使用起來是沒有問題的解孙,如果是靜態(tài)庫則需要加上上面的方法坑填。
  • 如果有很多關于符號表的警告,這時需要將Generate Debug Symbols設置為NO即可關閉符號表警告弛姜。

Apple 移動設備處理器指令集

ARM
arm的意思其實是指處理器的品牌脐瑰,ARM是英國Acorn有限公司設計的低功耗成本的RISC微處理器。
ARM處理器廷臼,特點是體積小苍在、低功耗、低成本荠商、高性能寂恬,所以幾乎所有手機處理器都基于ARM,在嵌入式系統(tǒng)中應用廣泛莱没。

ARM處理器指令集
armv6|armv7|armv7s|arm64都是ARM處理器的指令集掠剑,這些指令集都是向下兼容的,例如armv7指令集兼容armv6郊愧,只是使用armv6的時候無法發(fā)揮出其性能朴译,無法使用armv7的新特性井佑,從而會導致程序執(zhí)行效率沒那么高。
還有兩個我們也很熟悉的指令集:i386|x86_64 是Mac處理器的指令集眠寿,i386是針對intel通用微處理器32架構的躬翁。x86_64是針對x86架構的64位處理器。所以當使用iOS模擬器的時候會遇到i386|x86_64盯拱,iOS模擬器沒有arm指令集盒发。

iOS 移動設備指令集

armv6 設備: iPhone、 iPhone2狡逢、iPhone3G宁舰、第一代、第二代 iPod Touch
armv7 設備: iPhone3GS奢浑、iPhone4蛮艰、iPhone4S、iPad雀彼、iPad2壤蚜、iPad3(The New iPad)、iPad mini徊哑、iPod Touch 3G袜刷、iPod Touch4
armv7s 設備: iPhone5、iPhone5C莺丑、iPad4(iPad with Retina Display)
arm64 設備:iPhoneX著蟹、iPhone8 plus、iPhone8梢莽、iPhone7 plus萧豆、iPhone7、iPhone6s蟹漓、iphone6s plus炕横、iPhone6、iPhone6 plus葡粒、iPhone5S份殿、iPad Air、 iPad mini2(iPad mini with Retina Display)
注:
模擬器32位的處理器需要i386的架構嗽交,64位的處理器需要x86_64的架構卿嘲。
真機32位需要arm7,或者arm7s架構夫壁,64位需要arm64架構拾枣。

Xcode Build Setting中指令集相關選項釋義

  • Architectures
    指定工程被編譯成可支持哪些指令集類型,而支持的指令集越多,就會編譯出包含多個指令集代碼的數(shù)據(jù)包梅肤,對應生成二進制包就越大司蔬,也就是ipa包會變大。
  • Valid Architectures
    限制可能被支持的指令集的范圍姨蝴,也就是Xcode編譯出來的二進制包類型最終從這些類型產生俊啼,而編譯出哪種指令集的包,將由Architectures與Valid Architectures(因此這個不能為空)的交集來確定左医。
    比如 Valid Architectures設置的支持arm指令集版本有:armv7/armv7s/arm64授帕,對應的Architectures設置的支持arm指令集版本有:armv7s,這時Xcode只會生成一個armv7s指令集的二進制包浮梢。
    再比如:將Architectures支持arm指令集設置為:armv7,armv7s跛十,對應的Valid Architectures的支持的指令集設置為:armv7s,arm64,那么此時秕硝,XCode生成二進制包所支持的指令集只有armv7s
  • Build Active Architecture Only
    指定是否只對當前連接設備所支持的指令集編譯
    當其值設置為YES芥映,這個屬性設置為yes,是為了debug的時候編譯速度更快缝裤,它只編譯當前的architecture版本屏轰,而設置為no時颊郎,會編譯所有的版本憋飞。 所以,一般debug的時候可以選擇設置為yes姆吭,release的時候要改為no榛做,以適應不同設備。
查看 .framework 支持的指令集 和 模擬器庫 真機庫 合并
  • 使用 lipo -info 查看最終庫的信息
lipo -info Cat
Cat 是 framework 包內的 編譯后的 exec 文件

可以看到 Debug-iphonesimulator 下的 .framework 支持的指令集是 x86_64, 即 Cat is architecture: x86_64

下面看看真機狀態(tài)下打包的 .framework 所支持的指令集内狸,沒錯是 arm64 检眯,此只能在真機上運行
  • 如果需要 framework 既可以在模擬器上運行又可以在真機上運行,就需要使用 lipo -create 模擬器庫 真機庫 -output 最終庫 進行合并
lipo -create 模擬器庫內的exec文件路徑 真機庫內的exec文件路徑 -output 合并后的庫名
注意:此時只是把兩個庫的exec文件合并了昆淡, 然后把這個合并后的 exec 文件锰瘸,替換兩個庫的任意一個,被替換的額那個庫就是我們需要的了昂灵,此時這個庫即可在模擬器上運行也可在真機上運行避凝,親測可行!

到此就結束了眨补,怕自己忘了管削,記錄一下...

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市撑螺,隨后出現(xiàn)的幾起案子含思,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件含潘,死亡現(xiàn)場離奇詭異饲做,居然都是意外死亡,警方通過查閱死者的電腦和手機遏弱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門艇炎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腾窝,你說我怎么就攤上這事缀踪。” “怎么了虹脯?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵驴娃,是天一觀的道長。 經(jīng)常有香客問我循集,道長唇敞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任咒彤,我火速辦了婚禮疆柔,結果婚禮上,老公的妹妹穿的比我還像新娘镶柱。我一直安慰自己旷档,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布歇拆。 她就那樣靜靜地躺著鞋屈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪故觅。 梳的紋絲不亂的頭發(fā)上厂庇,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音输吏,去河邊找鬼权旷。 笑死,一個胖子當著我的面吹牛贯溅,可吹牛的內容都是我干的拄氯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盗迟,長吁一口氣:“原來是場噩夢啊……” “哼坤邪!你這毒婦竟也來了?” 一聲冷哼從身側響起罚缕,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤艇纺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黔衡,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡蚓聘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盟劫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夜牡。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖侣签,靈堂內的尸體忽然破棺而出塘装,到底是詐尸還是另有隱情,我是刑警寧澤影所,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布蹦肴,位于F島的核電站,受9級特大地震影響猴娩,放射性物質發(fā)生泄漏阴幌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一卷中、第九天 我趴在偏房一處隱蔽的房頂上張望矛双。 院中可真熱鬧,春花似錦蟆豫、人聲如沸议忽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徙瓶。三九已至毛雇,卻和暖如春嫉称,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背灵疮。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工织阅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人震捣。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓荔棉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蒿赢。 傳聞我的和親對象是個殘疾皇子润樱,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內容