列表
cocoapods 1.5更新描述
xcode9支持swift靜態(tài)庫,在Cocoapods 1.5.0中支持了導入swift靜態(tài)庫,不需要再指定 use_frameworks! 。需要注意的是當你的一個swift pod模塊依賴一個OC pod模塊時需要開啟Modular Headers,三種方式:
1.在podfile中添加 use_modular_headers! ,這種方式將使得所有的pod模塊都能使用@import導入。
platform :ios, '9.0'
use_modular_headers!
target 'staticpod' do
pod 'SwiftModule', :path => '../SwiftModule'
pod 'ObjectiveModule', :path => '../ObjectiveModule'
2.在podfile中對應的pod模塊后添加 :modular_headers => true ,這種方式將使得對應的pod模塊能使用@import導入。
pod 'ObjectiveModule', :path => '../ObjectiveModule', :modular_headers => true
3.在模塊的podspec中添加 'DEFINES_MODULE' => 'YES' 到你的 pod_target_xcconfig 中,這種方式將指定你的podspec的模塊能使用@import導入。
spec.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
PS:在cocoapod不使用 use_frameworks! 時,OC模塊無法使用@import導入,use_modular_headers! 的意思是OC模塊可以使用@import
#import和@import區(qū)別
#import :
? 我相信每個開發(fā)者都寫過這樣的代碼 #import <FrameworkFoo/HeaderBar.h> ,用來引用其他的頭文件。熟悉C或者C++的童鞋可能會知道,在C和C++里是沒有#import的,只有#include(雖然GCC現(xiàn)在為C和C++做了特殊處理使得import可以被編譯),用來包含頭文件。#include做的事情其實就是簡單的復制粘貼,將目標.h文件中的內(nèi)容一字不落地拷貝到當前文件中,并替換掉這句include,而#import實質(zhì)上做的事情和#include是一樣的,只不過OC為了避免重復引用可能帶來的編譯錯誤(這種情況在引用關系復雜的時候很可能發(fā)生,比如B和C都引用了A,D又同時引用了B和C,這樣A中定義的東西就在D中被定義了兩次,重復了),而加入了#import,從而保證每個頭文件只會被引用一次。
@import :
? Modules相當于將框架進行了封裝,然后加入在實際編譯之時加入了一個用來存放已編譯添加過的Modules列表。如果在編譯的文件中引用到某個Modules的話,將首先在這個列表內(nèi)查找,找到的話說明已經(jīng)被加載過則直接使用已有的,如果沒有找到,則把引用的頭文件編譯后加入到這個表中。這樣被引用到的Modules只會被編譯一次,但是在開發(fā)時又不會被意外使用到,從而同時解決了編譯時間和引用泛濫兩方面的問題。
測量Pre-mainTime
一個App在執(zhí)行main函數(shù)前包括app delegate的系列方法如applicationWillFinishLaunching時,會做許多系統(tǒng)級別的準備.而在iOS10之前,開發(fā)者很難清楚自己App為何啟動加載慢.而通過在工程的scheme中添加環(huán)境變量 DYLD_PRINT_STATISTICS ,設置Value為 1 ,App啟動加載時就會有啟動過程的日志輸出. 現(xiàn)在(iOS 10之后)Apple對DYLD_PRINT_STATISTICS的日志輸出結果進行了簡化,使得更容易讓開發(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()函前主要進行的工作內(nèi)容和時間花費,Session上也對每一階段加載過程具體內(nèi)容進行了詳細的敘述,有興趣地可觀看該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 ,設置Value為 1 。App啟動加載時就會有啟動過程的日志輸出,可以查看pre-main時間
3.在工程中添加swift橋接文件 staticpod-Bridging-Header.h ,以支持混編
4.通過添加和刪除 use_framework! 對比測試pre-main、ipa大小。PS:測試pre-main時每次請先把App從iphone中刪除,避免iphone緩存影響
pre-main測試對比:
//靜態(tài)庫
//第一次:
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%)
//動態(tài)庫
//第一次:
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大小對比:
| 靜態(tài)庫 | 動態(tài)庫 |
|---|---|
| 97.9MB | 103.5MB |
- 結論:
1.通過pre-main測試對比發(fā)現(xiàn),在啟動時靜態(tài)庫dylib loading time速度明顯提升。
2.通過ipa大小對比發(fā)現(xiàn),靜態(tài)庫比動態(tài)庫ipa大小有所縮小。
注意事項
1.swift橋接文件
2.swift pod編譯需要修改版本
3.在使用靜態(tài)庫時,無法使用 #import <Module/Module-Swift.h> 導入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啟動速度"
[3]: https://blog.csdn.net/Leemin_ios/article/details/51208642 "#import、#include、@import modules區(qū)別"