“我报名参加金石方案1期应战——分割10万奖池,这是我的第1篇文章,点击检查活动概略”

一、 APP 发起类型

APP发起分为 冷发起热发起两种

  • 冷发起: APP的icon从点击发起前,它的进程不在系统里,需求新创建一个进程分配给它的发起的情况。
  • 热发起: APP在发起后用户将APP退到后台,在APP的进程还在系统里的情况下,用户从头发起进入APP的进程。(这个进程做的作业比较少)

二、APP发起的三个阶段、

  • pre-main ( main()函数发起之前)
  • main() 函数之后发起之后
  • 首屏烘托结束

1、pre-main: ( main()函数发起之前)

此进程是发起第一步,首要包括四个进程:

  • 加载动态库耗时 (dylib loading ):
  • 修改符号和绑定符号耗时 (rebase/binding
  • OC类注册 耗时(ObjC setup time)
  • +load()函数耗时 (initializer

这几个进程的耗时,我们能够经过配备环境变量打印出来进行检查:

  • 首要我们进入Edit Scheme,然后选中Run -> Arguments -> Environment Variables
  • 然后配备key为: DYLD_PRINT_STATISTICS
    iOS 功用优化 -- APP发起时间解析
  • 然后我们发起项目,就会发现xcode会打印出pre-main的耗时,每个小进程的耗时都会闪现出来:
    iOS 功用优化 -- APP发起时间解析
    下面我们剖析下每个小进程的首要功用:
  • dylib loading: 首要是载入动态库,这个进程会去加载APP运用到的一切动态库,而动态库之间有自己的依靠联系,所以会消耗时间去查找和读取。

优化

  • 尽量运用系统库: 由于系统的动态库现已做了优化
  • 尽量减少动态库的运用: 动态库运用尽量不要逾越6个,假设逾越,最好去兼并他们运用
  • 将动态库替换为静态库运用:静态库的运用会简化时间
  • rebase/binding : rebase:内部调整指针的指向,Mach-o被加载到内存的时分会添加随机地址(ASLR),这个随机的地址跟代码和数据指向的旧地址会有差错。dyld 需求修改这个差错,做法便是将 dylib 内部的指针地址都加上这个偏移量。 binding:将指针指向镜像(MachO文件)外部的内容,binding便是将这个二进制调用的外部符号进行绑定的进程。

优化:

  • Objc setup:oc 类的加载 1、读取二进制文件的 DATA 段内容,找到与 objc 相关的信息 2、注册 Objc 类,ObjC Runtime 需求保护一张映射类名与类的全局表。当加载一个 MachO 时,它定义的一切的类都需求被注册到这个全局表中; 3、读取 protocol 以及 category 的信息,把category的定义刺进方法列表 (category registration)

优化: 尽量减少类的运用:有的地方能够用结构体替代 删去无用、扔掉的类

  • initializer: 函数初始化 1、Objc的 +load()函数调用 2、C++的结构函数的调用

优化: 尽量减少在+load()里面添加放法,减少+load()函数的复杂度 尽量不要用C++虚函数

2、main函数阶段的优化

main函数首要的进程

调用 main 函数 调用UIApplicationMain() 调用applicationWillFinishLaunching

main函数之后首要是实行didFinishLaunching方法,这个方法首要是实行各种业务。可是有些任务不需求当即实行,这时分我能够对其采取推延加载,减少对发起时间的影响。 首要的业务首要分三类:初始化第三方SDK环境配备自己的工具栏的初始化,针对这三大类进行优化:

  • 减少发起初始化流程: 针对一些方法流程,能懒加载的懒加载,能推延的推延实行,尽量少占用主线程的发起时间
  • 能运用多线程来初始化的,就运用多线程
  • 尽量防止运用xib/SB搭建UI,最好运用纯代码搭建
  • 删去扔掉的类、方法等

3、首屏加载的优化

上面的两种优化方法,在小项目中都是毫秒级的,能优化的空间不到,效果有时分用户底子看不出来,用户能感知的是从点击图标到使用主页加载出来的整个进程,所以这时分首屏的优化就显得很重要了,这儿大致说下首屏优化的几个方面:

  • 从本地回去缓存数据加载

此方法适宜,主页数据不需求及时更新的情况,我们能够把上一次央求到数据缓存在磁盘或许数据库中,发起的的时分,直接从磁盘中加载,加载结束之后再去央求网络数据,这时分假设数据不一样就改写界面,并从头缓存数据,以待下次运用

  • 运用骨架屏

这个适宜需求展示实时性比较高的情况,我们在网络央求的时分,去展示骨架屏,给用户一个数据行将出来的感觉

  • 拆分央求接口
  • 这种情况适宜,主页展示多模块的数据,且模块之间的依靠性比较弱的情况。
  • 我们把每个模块的数据央求都放在子线程去处理,数据照应后在子线程结束相关的数据预处理,然后去主线程烘托,这样就把数据分开来,哪个数据先回来,先去烘托哪个模块
  • 当然,有时分我们没必要一次央求一切的模块数据,假设一个模块的数据,不会在第一屏闪现,需求在滑动后才干看到的时分,我们就能够对此模块的数据进行推延央求,用到的时分才去央求烘托
  • 推延其他信息配备服务
  • 关于用到的第三方服务,我们能够推延几秒,放在烘托结束之后去配备
  • 关于有时分主页我们需求去获取晋级信息或许一些其他的配备,也能够放在烘托之后再去央求配备