pod使用静态库,提升App启动速度,降低包大小

列表

  • cocoapod1.5更新描述
  • #import和@import区别
  • 测量Pre-main Time
  • demo案例
  • 注意事项

cocoapods 1.5更新描述

xcode9支持swift静态库,在Cocoapods 1.5.0中支持了导入swift静态库,不需要再指定 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区别

#import :

​ 我相信每个开发者都写过这样的代码 #import ,用来引用其他的头文件。熟悉C或者C++的童鞋可能会知道,在C和C++里是没有#import的,只有#include(虽然GCC现在为C和C++做了特殊处理使得import可以被编译),用来包含头文件。#include做的事情其实就是简单的复制粘贴,将目标.h文件中的内容一字不落地拷贝到当前文件中,并替换掉这句include,而#import实质上做的事情和#include是一样的,只不过OC为了避免重复引用可能带来的编译错误(这种情况在引用关系复杂的时候很可能发生,比如B和C都引用了A,D又同时引用了B和C,这样A中定义的东西就在D中被定义了两次,重复了),而加入了#import,从而保证每个头文件只会被引用一次。

@import :

​ Modules相当于将框架进行了封装,然后加入在实际编译之时加入了一个用来存放已编译添加过的Modules列表。如果在编译的文件中引用到某个Modules的话,将首先在这个列表内查找,找到的话说明已经被加载过则直接使用已有的,如果没有找到,则把引用的头文件编译后加入到这个表中。这样被引用到的Modules只会被编译一次,但是在开发时又不会被意外使用到,从而同时解决了编译时间和引用泛滥两方面的问题。

测量Pre-mainTime

一个App在执行main函数前包括app delegate的系列方法如applicationWillFinishLaunching时,会做许多系统级别的准备.而在iOS10之前,开发者很难清楚自己App为何启动加载慢.而通过在工程的scheme中添加环境变量 DYLD_PRINT_STATISTICS ,设置Value为 1 ,App启动加载时就会有启动过程的日志输出. 现在(iOS 10之后)Apple对DYLD_PRINT_STATISTICS的日志输出结果进行了简化,使得更容易让开发者理解.

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%)

输出内容展示了系统调用main()函前主要进行的工作内容和时间花费,Session上也对每一阶段加载过程具体内容进行了详细的叙述,有兴趣地可观看该Session.

demo案例

1.新建工程staticpod,添加如下Podfile文件,执行 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中添加环境变量 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测试对比:

//静态库
//第一次:
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%)

//动态库
//第一次:
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大小对比:

静态库 动态库
97.9MB 103.5MB
  1. 结论:
    1.通过pre-main测试对比发现,在启动时静态库dylib loading time速度明显提升。
    2.通过ipa大小对比发现,静态库比动态库ipa大小有所缩小。

注意事项

1.swift桥接文件

2.swift pod编译需要修改版本

3.在使用静态库时,无法使用 #import 导入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之优化App启动速度"
[3]: https://blog.csdn.net/Leemin_ios/article/details/51208642 "#import、#include、@import modules区别"

你可能感兴趣的:(pod使用静态库,提升App启动速度,降低包大小)