写点什么

Xcode13 适配之打印启动时间

  • 2021 年 12 月 10 日
  • 本文字数:1515 字

    阅读完需:约 5 分钟

Xcode13 适配之打印启动时间

Xcode13 上统计启动时长的变量 DYLD_PRINT_STATISTICS 失效了。团队中需要保留每次的启动时间以作检验优化标准。在网上找到下面文章,写了个获取启动时间工具类。


#import "AppLaunchTime.h"


#import <sys/sysctl.h>


#import <mach/mach.h>


@implementation AppLaunchTime


double __t1; // 创建进程时间


double __t2; // before main


double __t3; // didfinsh


/// 获取进程创建时间


  • (CFAbsoluteTime)processStartTime {

  • if (__t1 == 0) {

  • }

  • return __t1;


}/// 开始记录:在 DidFinish 中调用


  • (void)mark {

  • double __t1 = [LGAppLaunchTime processStartTime];

  • dispatch_async(dispatch_get_main_queue(), ^{ // 确保 didFihish 代码执行后调用

  • });}


/// 构造方法在 main 调用前调用/// 获取 pre-main()阶段的结束时间点相对容易,可以直接取 main()主函数的开始执行时间点.推荐使用__attribute__((constructor)) 构建器函数的被调用时间点作为 pre-main()阶段结束时间点:__t2 能最大程度实现解耦:


void static attribute((constructor)) before_main() {


if (__t2 == 0) {
__t2 = CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
}
复制代码


}


@end 复制代码


  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  • [LGAppLaunchTime mark];...复制代码


pre-main()阶段开始时间:__t1 苹果公司并没有直接向开发者提供内部统计时间字段以供开发者直接获取 App 的启动开始时刻点,目前行业内主要有两种标准作为 App 的启动时间点:


第一种标准:以名称+(void)load 方法被调用时的时间点 由于+(void)load 方法被调用的时间点发生 Initializer 初始化配置阶段, 根据(CompileSources)编译资源规则下动态库的加载顺序顺序的调用相应类下的+(void)load 方法,因为动态库的加载顺序是递归加载的,所以我们只要找到最内部的叶子节点的动态库,然后在这个最内部叶子结点动态库中+(void)load 方法重构以记录启动时间作为开始时间点。这种方式没有统计到 Initializer 初始化配置阶段前面部分所消耗的那些时间,比如在 Initializer 初始化配置阶段前面增加动态库、Category 等造成的耗时并不能被及时发现统计。


第二种标准:获取整个进程创建(从开始到结束)消耗时间 App 从源头配置直至运行整个过程实际上是一个逻辑进程,如果能获取到逻辑进程的起步创建时间即 exec()可执行函数触发阶段的触动时间点作为整个 app 逻辑进程的开始时间点,能够更提前记录到 App 的启动开始时间点。


pre-main()阶段结束时间点:__t2


获取 pre-main()阶段的结束时间点相对容易,可以直接取 main()主函数的开始执行时间点。 推荐使用__attribute__((constructor)) 构建器函数的被调用时间点作为 pre-main()阶段结束时间点:__t2


为什么不用最后一个 load 方法执行时间作为 pre-main()阶段的结束时间点?因为在超大型工程中我们没办法确定哪个名称 load 方法是最后一个被执行 load 方法。。。


启动动作正式完成对应的时间点:__t3 启动动作正式完成对应的时间点一般以 didFinishLaunchingWithOptions:已完成启动对应的代理协议函数的结束时间点,但 didFinishLaunchingWithOptions:已完成启动对应的代理协议函数的结束时间点(仅仅对应着光点初步渲染出现)其实不包括光点出现之后启动图动画渲染的时间消耗,而启动图动画执行完成后的时间点更加接近于用户的感官。可以在执行 didFinishLaunchingWithOptions: 的 runloop 循环的后面的循环来获取时间.


最后如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163 相互学习,我们会有专业的技术答疑解惑


如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点 star: https://gitee.com/ZhongBangKeJi/CRMEB不胜感激 !

用户头像

还未添加个人签名 2021.11.02 加入

CRMEB就是客户关系管理+营销电商系统实现公众号端、微信小程序端、H5端、APP、PC端用户账号同步,能够快速积累客户、会员数据分析、智能转化客户、有效提高销售、会员维护、网络营销的一款企业应用

评论

发布
暂无评论
Xcode13 适配之打印启动时间