列表
cocoapods 1.5更新描述
xcode9支持swift靜態(tài)庫(kù),在Cocoapods 1.5.0中支持了導(dǎo)入swift靜態(tài)庫(kù),不需要再指定 use_frameworks! 。需要注意的是當(dāng)你的一個(gè)swift pod模塊依賴一個(gè)OC pod模塊時(shí)需要開啟Modular Headers,三種方式:
1.在podfile中添加 use_modular_headers! ,這種方式將使得所有的pod模塊都能使用@import導(dǎo)入。
platform :ios, '9.0'
use_modular_headers!
target 'staticpod' do
pod 'SwiftModule', :path => '../SwiftModule'
pod 'ObjectiveModule', :path => '../ObjectiveModule'
2.在podfile中對(duì)應(yīng)的pod模塊后添加 :modular_headers => true ,這種方式將使得對(duì)應(yīng)的pod模塊能使用@import導(dǎo)入。
pod 'ObjectiveModule', :path => '../ObjectiveModule', :modular_headers => true
3.在模塊的podspec中添加 'DEFINES_MODULE' => 'YES' 到你的 pod_target_xcconfig 中,這種方式將指定你的podspec的模塊能使用@import導(dǎo)入。
spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
PS:在cocoapod不使用 use_frameworks! 時(shí),OC模塊無(wú)法使用@import導(dǎo)入,use_modular_headers! 的意思是OC模塊可以使用@import
#import和@import區(qū)別
#import :
? 我相信每個(gè)開發(fā)者都寫過(guò)這樣的代碼 #import <FrameworkFoo/HeaderBar.h> ,用來(lái)引用其他的頭文件。熟悉C或者C++的童鞋可能會(huì)知道,在C和C++里是沒有#import的,只有#include(雖然GCC現(xiàn)在為C和C++做了特殊處理使得import可以被編譯),用來(lái)包含頭文件。#include做的事情其實(shí)就是簡(jiǎn)單的復(fù)制粘貼,將目標(biāo).h文件中的內(nèi)容一字不落地拷貝到當(dāng)前文件中,并替換掉這句include,而#import實(shí)質(zhì)上做的事情和#include是一樣的,只不過(guò)OC為了避免重復(fù)引用可能帶來(lái)的編譯錯(cuò)誤(這種情況在引用關(guān)系復(fù)雜的時(shí)候很可能發(fā)生,比如B和C都引用了A,D又同時(shí)引用了B和C,這樣A中定義的東西就在D中被定義了兩次,重復(fù)了),而加入了#import,從而保證每個(gè)頭文件只會(huì)被引用一次。
@import :
? Modules相當(dāng)于將框架進(jìn)行了封裝,然后加入在實(shí)際編譯之時(shí)加入了一個(gè)用來(lái)存放已編譯添加過(guò)的Modules列表。如果在編譯的文件中引用到某個(gè)Modules的話,將首先在這個(gè)列表內(nèi)查找,找到的話說(shuō)明已經(jīng)被加載過(guò)則直接使用已有的,如果沒有找到,則把引用的頭文件編譯后加入到這個(gè)表中。這樣被引用到的Modules只會(huì)被編譯一次,但是在開發(fā)時(shí)又不會(huì)被意外使用到,從而同時(shí)解決了編譯時(shí)間和引用泛濫兩方面的問(wèn)題。
測(cè)量Pre-mainTime
一個(gè)App在執(zhí)行main函數(shù)前包括app delegate的系列方法如applicationWillFinishLaunching時(shí),會(huì)做許多系統(tǒng)級(jí)別的準(zhǔn)備.而在iOS10之前,開發(fā)者很難清楚自己App為何啟動(dòng)加載慢.而通過(guò)在工程的scheme中添加環(huán)境變量 DYLD_PRINT_STATISTICS ,設(shè)置Value為 1 ,App啟動(dòng)加載時(shí)就會(huì)有啟動(dòng)過(guò)程的日志輸出. 現(xiàn)在(iOS 10之后)Apple對(duì)DYLD_PRINT_STATISTICS的日志輸出結(jié)果進(jìn)行了簡(jiǎn)化,使得更容易讓開發(fā)者理解.
Total pre-main time: 1.5 seconds (100.0%)
dylib loading time: 927.09 milliseconds (58.8%)
rebase/binding time: 42.65 milliseconds (2.7%)
ObjC setup time: 365.58 milliseconds (23.2%)
initializer time: 239.06 milliseconds (15.1%)
slowest intializers :
libSystem.B.dylib : 16.71 milliseconds (1.0%)
libMainThreadChecker.dylib : 111.62 milliseconds (7.0%)
ModelIO : 39.38 milliseconds (2.5%)
staticpod : 76.22 milliseconds (4.8%)
輸出內(nèi)容展示了系統(tǒng)調(diào)用main()函前主要進(jìn)行的工作內(nèi)容和時(shí)間花費(fèi),Session上也對(duì)每一階段加載過(guò)程具體內(nèi)容進(jìn)行了詳細(xì)的敘述,有興趣地可觀看該Session.
demo案例
1.新建工程staticpod,添加如下Podfile文件,執(zhí)行 pod install
platform :ios, '9.0'
#use_frameworks!
use_modular_headers!
target 'staticpod' do
#OC模塊
pod 'Qiniu'
pod 'HappyDNS'
pod 'Masonry'
pod 'MJRefresh'
pod 'SDWebImage'
pod 'MJExtension'
pod 'pop'
pod 'FSCalendar'
pod 'FLAnimatedImage'
pod 'AFNetworking'
#swift模塊
pod 'Alamofire'
pod 'SwiftyJSON'
pod 'DZNEmptyDataSet'
pod 'lottie-ios'
pod 'FileKit'
pod 'SwiftyUserDefaults'
pod 'Hero'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = '4.1'
end
end
end
2.在工程的scheme中添加環(huán)境變量 DYLD_PRINT_STATISTICS ,設(shè)置Value為 1 。App啟動(dòng)加載時(shí)就會(huì)有啟動(dòng)過(guò)程的日志輸出,可以查看pre-main時(shí)間
3.在工程中添加swift橋接文件 staticpod-Bridging-Header.h ,以支持混編
4.通過(guò)添加和刪除 use_framework! 對(duì)比測(cè)試pre-main、ipa大小。PS:測(cè)試pre-main時(shí)每次請(qǐng)先把App從iphone中刪除,避免iphone緩存影響
pre-main測(cè)試對(duì)比:
//靜態(tài)庫(kù)
//第一次:
Total pre-main time: 1.5 seconds (100.0%)
dylib loading time: 927.09 milliseconds (58.8%)
rebase/binding time: 42.65 milliseconds (2.7%)
ObjC setup time: 365.58 milliseconds (23.2%)
initializer time: 239.06 milliseconds (15.1%)
slowest intializers :
libSystem.B.dylib : 16.71 milliseconds (1.0%)
libMainThreadChecker.dylib : 111.62 milliseconds (7.0%)
ModelIO : 39.38 milliseconds (2.5%)
staticpod : 76.22 milliseconds (4.8%)
//第二次:
Total pre-main time: 1.2 seconds (100.0%)
dylib loading time: 899.49 milliseconds (72.0%)
rebase/binding time: 25.12 milliseconds (2.0%)
ObjC setup time: 222.38 milliseconds (17.8%)
initializer time: 100.92 milliseconds (8.0%)
slowest intializers :
libSystem.B.dylib : 10.80 milliseconds (0.8%)
libMainThreadChecker.dylib : 27.79 milliseconds (2.2%)
staticpod : 38.54 milliseconds (3.0%)
//第三次:
Total pre-main time: 1.4 seconds (100.0%)
dylib loading time: 964.68 milliseconds (67.1%)
rebase/binding time: 26.76 milliseconds (1.8%)
ObjC setup time: 300.70 milliseconds (20.9%)
initializer time: 143.86 milliseconds (10.0%)
slowest intializers :
libSystem.B.dylib : 11.79 milliseconds (0.8%)
libMainThreadChecker.dylib : 55.83 milliseconds (3.8%)
staticpod : 49.46 milliseconds (3.4%)
//動(dòng)態(tài)庫(kù)
//第一次:
Total pre-main time: 1.9 seconds (100.0%)
dylib loading time: 1.5 seconds (81.9%)
rebase/binding time: 41.20 milliseconds (2.1%)
ObjC setup time: 184.62 milliseconds (9.4%)
initializer time: 126.52 milliseconds (6.4%)
slowest intializers :
libSystem.B.dylib : 11.67 milliseconds (0.5%)
libMainThreadChecker.dylib : 75.59 milliseconds (3.8%)
//第二次:
Total pre-main time: 2.8 seconds (100.0%)
dylib loading time: 2.3 seconds (82.7%)
rebase/binding time: 29.70 milliseconds (1.0%)
ObjC setup time: 302.37 milliseconds (10.7%)
initializer time: 153.19 milliseconds (5.4%)
slowest intializers :
libSystem.B.dylib : 18.91 milliseconds (0.6%)
libMainThreadChecker.dylib : 58.05 milliseconds (2.0%)
//第三次:
Total pre-main time: 1.7 seconds (100.0%)
dylib loading time: 1.6 seconds (91.7%)
rebase/binding time: 41.66 milliseconds (2.3%)
ObjC setup time: 34.16 milliseconds (1.9%)
initializer time: 69.59 milliseconds (3.9%)
slowest intializers :
libSystem.B.dylib : 13.77 milliseconds (0.7%)
ipa大小對(duì)比:
| 靜態(tài)庫(kù) | 動(dòng)態(tài)庫(kù) |
|---|---|
| 97.9MB | 103.5MB |
- 結(jié)論:
1.通過(guò)pre-main測(cè)試對(duì)比發(fā)現(xiàn),在啟動(dòng)時(shí)靜態(tài)庫(kù)dylib loading time速度明顯提升。
2.通過(guò)ipa大小對(duì)比發(fā)現(xiàn),靜態(tài)庫(kù)比動(dòng)態(tài)庫(kù)ipa大小有所縮小。
注意事項(xiàng)
1.swift橋接文件
2.swift pod編譯需要修改版本
3.在使用靜態(tài)庫(kù)時(shí),無(wú)法使用 #import <Module/Module-Swift.h> 導(dǎo)入swift文件,必須使用@import Module
參考:
[1]: http://blog.cocoapods.org/CocoaPods-1.5.0/ "Cocoapods 1.5.0更新文檔"
[2]: https://blog.csdn.net/khlljm/article/details/52386594 "WWDC之優(yōu)化App啟動(dòng)速度"
[3]: https://blog.csdn.net/Leemin_ios/article/details/51208642 "#import、#include、@import modules區(qū)別"