IOS应用的方法耗时、加载视图耗时的监测方法及系统
技术领域
本发明涉及IOS应用技术领域,具体涉及一种IOS应用的方法耗时、加载视图耗时的监测方法及系统。
背景技术
在移动应用的开发过程中,可能会遇到一些性能瓶颈,例如程序运行的卡顿或内存无法正确的释放,都无法得到很好的监控或反馈。一般的方法是将手机连上电脑,利用Xcode(一种Mac OS X操作系统上的集成开发工具)所带的Instrument工具进行监控。Xcode自带的Instrument工具是一个以独立APP形式存在的工具集,包含了很多强大的检测功能:其中包括在真机和模拟器上进行性能测试,对APP进行性能分析,检查一个或多个应用或进程的行为。Instrument工具主要用于在调试过程中随时发现问题,及时优化。但是Instrument工具只能供有应用源码的程序员使用,因此必须连接电脑,无法测量用户真实使用场景下的性能,即无法在IOS App发布之后依然对IOS App的运行情况进行有效的监控。
发明内容
针对现有技术中存在的缺陷,本发明的目的在于提供一种IOS应用的方法耗时、加载视图耗时的监测方法及系统,实现IOS App发布之后对IOSApp的方法耗时的有效监控。
为达到以上目的,本发明采取的技术方案是:一种IOS应用的方法耗时监测方法,其用于监测所述IOS应用调用的主线程中各方法的调用耗时:
将objc_msgSend函数指针设置为hook函数;所述hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
IOS应用调用主线程中任一方法时,通过所述objc_msgSend函数指针调用hook函数,通过所述hook函数计算出调取主线程中该方法时objc_msgSend函数的调用耗时;通过调用hook函数分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时;
定义一个Objective-C的类,并实现该类的单例加载;通过所述Objective-C的类分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时并转换为所述Objective-C的类中的对象。
在上述技术方案的基础上,创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在所述头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在所述C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过所述objc_msgSend函数指针调用hook函数;拦截结果用于存储所述hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
在所述Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
用户选择开始监测IOS应用调用的主线程中各方法的调用耗时,通过OC层开始拦截API调用C语言层开始拦截API开始通过所述objc_msgSend函数指针调用hook函数,通过所述hook函数计算出的调用主线程中各方法时objc_msgSend函数的调用耗时;将计算出的调用主线程中各方法时objc_msgSend函数的调用耗时分别添加进所述拦截结果;
用户选择停止监测IOS应用调用的主线程中各方法的调用耗时,通过OC层停止拦截API调用C语言层停止拦截API停止通过所述objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从所述拦截结果中获取到调用主线程中各方法时objc_msgSend函数的调用耗时并置空所述拦截结果。
在上述技术方案的基础上,第二函数还用于从所述objc_msgSend函数的参数中获取调用主线程中方法的嵌套层级。
本发明还公开了一种IOS应用的方法耗时监测系统,包括:
函数指针替换模块,其用于将objc_msgSend函数指针替换为hook函数;所述hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
第一调用耗时计算模块,其用于IOS应用调用主线程中任一方法时,通过所述objc_msgSend函数指针调用hook函数,通过所述hook函数计算出调取主线程中该方法时objc_msgSend函数的调用耗时;通过调用hook函数分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时;
第一调用耗时获取模块,其用于定义一个Objective-C的类,并实现该类的单例加载;通过所述Objective-C的类分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时并转换为所述Objective-C的类中的对象。
在上述技术方案的基础上,所述IOS应用的方法耗时监测系统还包括C语言层API模块和OC层API模块;
C语言层API模块用于创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在所述头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在所述C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过所述objc_msgSend函数指针调用hook函数;拦截结果用于存储所述hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
OC层API模块用于在所述Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
所述第一调用耗时计算模块用于:用户选择开始监测IOS应用调用的主线程中各方法的调用耗时,通过OC层开始拦截API调用C语言层开始拦截API开始通过所述objc_msgSend函数指针调用hook函数,通过所述hook函数计算出的调用主线程中各方法时objc_msgSend函数的调用耗时;将计算出的调用主线程中各方法时objc_msgSend函数的调用耗时分别添加进所述拦截结果;
所述第一调用耗时获取模块用于:用户选择停止监测IOS应用调用的主线程中各方法的调用耗时,通过OC层停止拦截API调用C语言层停止拦截API停止通过所述objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从所述拦截结果中获取到调用主线程中各方法时objc_msgSend函数的调用耗时并置空所述拦截结果。
本发明还公开了一种IOS应用的加载视图耗时监测方法:
将objc_msgSend函数指针替换为hook函数;所述hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
创建视图控制器的分类,在所述视图控制器的分类被加载的时候通过runtime函数将视图控制器生命循环中的ViewDidLoad函数交换为第四函数,将ViewDidAppear函数交换为第五函数;
视图开始加载时,调用第四函数,所述第四函数通过所述objc_msgSend函数指针调用hook函数,通过所述hook函数计算出调取objc_msgSend函数的调用耗时;
视图加载结束时,调用第五函数,通过所述第五函数获取所述hook函数计算出的调取objc_msgSend函数的调用耗时。
在上述技术方案的基础上,创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在所述头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在所述C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过所述objc_msgSend函数指针调用hook函数;拦截结果用于存储所述hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
在所述Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
视图开始加载时,调用第四函数,第四函数调用OC层开始拦截API,通过OC层开始拦截API调用C语言层开始拦截API,开始通过所述objc_msgSend函数指针调用hook函数,通过所述hook函数计算出调取objc_msgSend函数的调用耗时,并将调取objc_msgSend函数的调用耗时添加进所述拦截结果;
视图加载结束时,调用第五函数,第五函数调用OC层停止拦截API,通过OC层停止通过所述objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从所述拦截结果中获取到调取objc_msgSend函数的调用耗时并置空所述拦截结果。
在上述技术方案的基础上,所述第二函数还用于从所述objc_msgSend函数的参数中获取调用主线程中方法的嵌套层级。
本发明还公开了一种IOS应用的加载视图耗时监测系统,包括:
函数指针替换模块,其用于将objc_msgSend函数指针替换为hook函数;所述hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
函数交换模块,其用于创建视图控制器的分类,在所述视图控制器的分类被加载的时候通过runtime函数将视图控制器生命循环中的ViewDidLoad函数交换为第四函数,将ViewDidAppear函数交换为第五函数;
第二调用耗时计算模块,其用于视图开始加载时,调用第四函数,第四函数通过所述objc_msgSend函数指针调用hook函数,通过调用所述hook函数计算出调取objc_msgSend函数的调用耗时;
第二调用耗时获取模块,其用于视图加载结束时,调用第五函数,通过第五函数获取所述hook函数计算出调取objc_msgSend函数的调用耗时。
在上述技术方案的基础上,所述IOS应用的加载视图耗时监测系统还包括C语言层API模块和OC层API模块;
所述C语言层API模块用于创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在所述头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在所述C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过所述objc_msgSend函数指针调用hook函数;拦截结果用于存储所述hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
所述OC层API模块用于在所述Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
所述第二调用耗时计算模块用于:视图开始加载时,通过OC层开始拦截API调用C语言层开始拦截API开始通过所述objc_msgSend函数指针调用hook函数,并将所述hook函数计算出的调取objc_msgSend函数的调用耗时添加进所述拦截结果;
所述第二调用耗时获取模块用于:视图加载结束时,通过OC层停止拦截API调用C语言层停止拦截API停止通过所述objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从所述拦截结果中获取到调取objc_msgSend函数的调用耗时并置空所述拦截结果。
与现有技术相比,本发明的优点在于:
本发明将objc_msgSend函数指针设置为hook函数;IOS应用调用主线程中任一方法时,通过objc_msgSend函数指针调用hook函数,通过hook函数计算出IOS应用调用主线程中该方法时objc_msgSend函数的调用耗时;通过调用hook函数可分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时,由于主线程中方法的调用都会对应objc_msgSend函数的调用,objc_msgSend函数的调用耗时即为调取主线程中方法时所耗费时间,从而实现对IOS应用运行时调用主线程中各方法的调用耗时监控。
同时,objc_msgSend函数为C语言层的函数,因此,要在IOS系统中展示hook函数获取的objc_msgSend函数的调用耗时,还需要通过Objective-C的类从C语言层获取objc_msgSend函数的调用耗时并转换成Objective-C的类中的对象。
定义C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API以及OC层开始拦截API和OC层停止拦截API,实现了对是否调用hook函数获取objc_msgSend函数的调用耗时的控制,便于用户控制耗时监控的开始时间和结束时间。
在上述方案的基础上,需要监测加载视图耗时时,创建视图控制器的分类,在视图控制器的分类被加载的时候通过runtime函数将ViewDidLoad函数交换为第四函数,将ViewDidAppear函数交换为第五函数;视图开始加载时,调用第四函数通过hook函数计算出调取objc_msgSend函数的调用耗时;视图加载结束时,调用第五函数获取hook函数计算出的调取objc_msgSend函数的调用耗时,从而实现IOS应用运行时对加载视图耗时的实时监控。
附图说明
图1为本发明实施例中IOS应用的方法耗时的监测系统的结构示意图;
图2为本发明实施例中IOS应用的加载视图耗时的监测系统的结构示意图。
具体实施方式
以下结合附图及实施例对本发明作进一步详细说明。
为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。
以下首先就本发明的术语进行解释和说明:
C语言文件及头文件:C语言文件,其后缀为.c。.c文件是程序文件,内含函数实现,变量定义等内容。头文件,其后缀为.h。.h文件是头文件,内含函数声明、宏定义、结构体定义等内容。
API(Application Programming Interface,应用程序编程接口),是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
Objective-C的类,类是核心支持面向对象编程及Objective-C的特点,通常被称为用户定义的类型。类是用来指定对象的形式,它结合了数据表示和方法操纵这些数据转换成一个整齐的包。
实现类单例加载,即保证一个类只生成一个实例对象。
objc_msgSend函数,objc_msgSend函数为IOS系统中负责消息发送的函数。在Objective-C中,主线程中方法的调用最终都会转为成消息发送,即主线程中方法的调用都会对应objc_msgSend函数的调用。因此,调取主线程中某一方法的调用耗时等同于对应的objc_msgSend函数的调用耗时。
runtime函数,Objective-C语言有一个运行时系统Objc Runtime,其实是一个Runtime库,将类结构体或对象结构体用runtime函数封装后,可以在程序运行时创建、检查、修改类、对象和它们的方法。
ViewDidLoad函数,viewDidLoad函数用于加载视图。
viewDidApper函数,UIViewController对象的视图已经加入到窗口时调用。
视图控制器(UIViewController),是iOS顶层视图的载体及控制器,用户与程序界面的交互都是由UIViewController来控制的,UIViewController管理UIView的生命周期及资源的加载与释放。
实施例1:
本发明实施例提供一种IOS应用的方法耗时监测方法,其用于监测IOS应用调用的主线程中各方法的调用耗时:
将objc_msgSend函数指针设置为hook函数;hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
IOS应用调用主线程中任一方法时,通过objc_msgSend函数指针调用hook函数,通过hook函数计算出调取主线程中该方法时objc_msgSend函数的调用耗时;通过调用hook函数分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时;
定义一个Objective-C的类,并实现该类的单例加载;通过Objective-C的类分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时并转换为Objective-C的类中的对象。
由于主线程中方法的调用都会对应objc_msgSend函数的调用,objc_msgSend函数的调用耗时即为调取主线程中方法时所耗费时间,从而实现对IOS应用运行时调用主线程中各方法的调用耗时监控。同时,objc_msgSend函数为C语言层的函数,因此,要在IOS系统中展示hook函数获取的objc_msgSend函数的调用耗时,还需要通过Objective-C的类从C语言层获取objc_msgSend函数的调用耗时并转换成Objective-C的类中的对象。
例如,主线程中依次执行方法A、B、C,通过hook函数可依次获取执行方法A时objc_msgSend函数的调用耗时、执行方法B时objc_msgSend函数的调用耗时、执行方法C时objc_msgSend函数的调用耗时。由于主线程中方法的调用都会对应objc_msgSend函数的调用,执行方法A时objc_msgSend函数的调用耗时即为调取主线程中方法A时的函数调用耗时,执行方法B时objc_msgSend函数的调用耗时即为调取主线程中方法B时的函数调用耗时,执行方法C时objc_msgSend函数的调用耗时即为调取主线程中方法C时的函数调用耗时,从而通过hook函数实现对IOS应用运行时调用主线程中各方法的调用耗时监控。
为了便于用户控制耗时监控的开始时间和结束时间,可通过定义C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API以及OC层开始拦截API和OC层停止拦截API,实现对是否调用hook函数获取objc_msgSend函数的调用耗时的控制,具体实现过程如下:
创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过objc_msgSend函数指针调用hook函数;拦截结果用于存储hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
在Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
用户选择开始监测IOS应用调用的主线程中各方法的调用耗时,通过OC层开始拦截API调用C语言层开始拦截API开始通过objc_msgSend函数指针调用hook函数,通过hook函数计算出的调用主线程中各方法时objc_msgSend函数的调用耗时;将计算出的调用主线程中各方法时objc_msgSend函数的调用耗时分别添加进拦截结果;
用户选择停止监测IOS应用调用的主线程中各方法的调用耗时,通过OC层停止拦截API调用C语言层停止拦截API停止通过objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从拦截结果中获取到调用主线程中各方法时objc_msgSend函数的调用耗时并置空拦截结果。
第二函数还用于从objc_msgSend函数的参数中获取调用主线程中方法的嵌套层级。如调用objc_msgSend函数时,主线程中方法D的内部调用函数为函数D1,函数D1的内部调用函数为D2,上述函数嵌套调用关系即为主线程中方法D的嵌套层级。
实施例2:
参见图1所示,本发明实施例公开了一种IOS应用的方法耗时监测系统,包括:
函数指针替换模块,其用于将objc_msgSend函数指针替换为hook函数;hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
第一调用耗时计算模块,其用于IOS应用调用主线程中任一方法时,通过objc_msgSend函数指针调用hook函数,通过hook函数计算出调取主线程中该方法时objc_msgSend函数的调用耗时;通过调用hook函数分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时;
第一调用耗时获取模块,其用于定义一个Objective-C的类,并实现该类的单例加载;通过Objective-C的类分别获取IOS应用调用主线程中各方法时objc_msgSend函数的调用耗时并转换为Objective-C的类中的对象。
IOS应用的方法耗时监测系统还包括C语言层API模块和OC层API模块;
C语言层API模块用于创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过objc_msgSend函数指针调用hook函数;拦截结果用于存储hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
OC层API模块用于在Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
第一调用耗时计算模块用于:用户选择开始监测IOS应用调用的主线程中各方法的调用耗时,通过OC层开始拦截API调用C语言层开始拦截API开始通过objc_msgSend函数指针调用hook函数,通过hook函数计算出的调用主线程中各方法时objc_msgSend函数的调用耗时;将计算出的调用主线程中各方法时objc_msgSend函数的调用耗时分别添加进拦截结果;
第一调用耗时获取模块用于:用户选择停止监测IOS应用调用的主线程中各方法的调用耗时,通过OC层停止拦截API调用C语言层停止拦截API停止通过objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从拦截结果中获取到调用主线程中各方法时objc_msgSend函数的调用耗时并置空拦截结果。
实施例3:
本发明实施例公开了一种IOS应用的加载视图耗时监测方法:
在实施例1和2的基础上,需要监测加载视图耗时时,创建视图控制器的分类,在视图控制器的分类被加载的时候通过runtime函数将ViewDidLoad函数交换为第四函数,将ViewDidAppear函数交换为第五函数;视图开始加载时,调用第四函数通过hook函数计算出调取objc_msgSend函数的调用耗时;视图加载结束时,调用第五函数获取hook函数计算出的调取objc_msgSend函数的调用耗时,从而实现IOS应用运行时对加载视图耗时的实时监控,其具体实施过程如下:
将objc_msgSend函数指针替换为hook函数;hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
创建视图控制器的分类,在视图控制器的分类被加载的时候通过runtime函数将视图控制器生命循环中的ViewDidLoad函数交换为第四函数,将ViewDidAppear函数交换为第五函数;
视图开始加载时,调用第四函数,第四函数通过objc_msgSend函数指针调用hook函数,通过hook函数计算出调取objc_msgSend函数的调用耗时;
视图加载结束时,调用第五函数,通过第五函数获取hook函数计算出的调取objc_msgSend函数的调用耗时。
创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过objc_msgSend函数指针调用hook函数;拦截结果用于存储hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
在Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
视图开始加载时,调用第四函数,第四函数调用OC层开始拦截API,通过OC层开始拦截API调用C语言层开始拦截API,开始通过objc_msgSend函数指针调用hook函数,通过hook函数计算出调取objc_msgSend函数的调用耗时,并将调取objc_msgSend函数的调用耗时添加进拦截结果;
视图加载结束时,调用第五函数,第五函数调用OC层停止拦截API,通过OC层停止通过objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从拦截结果中获取到调取objc_msgSend函数的调用耗时并置空拦截结果。
第二函数还用于从objc_msgSend函数的参数中获取调用主线程中方法的嵌套层级。如调用objc_msgSend函数时,主线程中方法D的内部调用函数为函数D1,函数D1的内部调用函数为D2,上述函数嵌套调用关系即为主线程中方法D的嵌套层级。
实施例4:
在实施例1和2的基础上,本实施例公开了一种IOS应用的加载视图耗时监测系统,参见图2所示,包括:
函数指针替换模块,其用于将objc_msgSend函数指针替换为hook函数;hook函数包括:第一函数,其用于获取objc_msgSend函数的参数;第二函数,其用于使用objc_msgSend函数的参数调取objc_msgSend函数并记录开始调取时间;第三函数,其用于objc_msgSend函数调取完毕时,记录objc_msgSend函数的调取结束时间,根据调取开始时间和调取结束时间计算出调取objc_msgSend函数的调用耗时;
函数交换模块,其用于创建视图控制器的分类,在视图控制器的分类被加载的时候通过runtime函数将视图控制器生命循环中的ViewDidLoad函数交换为第四函数,将ViewDidAppear函数交换为第五函数;
第二调用耗时计算模块,其用于视图开始加载时,调用第四函数,第四函数通过objc_msgSend函数指针调用hook函数,通过调用hook函数计算出调取objc_msgSend函数的调用耗时;
第二调用耗时获取模块,其用于视图加载结束时,调用第五函数,通过第五函数获取hook函数计算出调取objc_msgSend函数的调用耗时。
IOS应用的加载视图耗时监测系统还包括C语言层API模块和OC层API模块;
C语言层API模块用于创建一个C语言文件MethodCoreLib.c及其头文件MethodCoreLib.h;在头文件中创建C语言层开始拦截API,C语言层停止拦截API和C语言层获取拦截结果API;在C语言文件MethodCoreLib.c文件中定义两个全局变量:拦截开关和拦截结果;拦截开关用于控制开始或停止通过objc_msgSend函数指针调用hook函数;拦截结果用于存储hook函数计算出的调取objc_msgSend函数的调用耗时;在C语言层开始拦截API中设置拦截开关为开始,在C语言层停止拦截API中设置拦截开关为停止,在C语言层获取拦截结果API中设置将拦截结果传出并置空;
OC层API模块用于在Objective-C的类中定义OC层开始拦截API和OC层停止拦截API;OC层开始拦截API用于调用C语言层开始拦截API,OC层停止拦截API用于调用C语言层停止拦截API和C语言层获取拦截结果API;
第二调用耗时计算模块用于:视图开始加载时,通过OC层开始拦截API调用C语言层开始拦截API开始通过objc_msgSend函数指针调用hook函数,并将hook函数计算出的调取objc_msgSend函数的调用耗时添加进拦截结果;
第二调用耗时获取模块用于:视图加载结束时,通过OC层停止拦截API调用C语言层停止拦截API停止通过objc_msgSend函数指针调用hook函数,并通过C语言层获取拦截结果API从拦截结果中获取到调取objc_msgSend函数的调用耗时并置空拦截结果。
实施例5:
本发明实施例还公开了一种存储介质,该存储介质上存储有计算机程序,计算机程序被处理器执行时实现IOS应用的方法耗时监测方法或IOS应用的加载视图耗时监测方法。
实施例6:
本发明实施例还公开了一种电子设备,包括存储器和处理器,存储器上储存有在处理器上运行的计算机程序,处理器执行计算机程序时实现IOS应用的方法耗时监测方法或IOS应用的加载视图耗时监测方法。
本发明不局限于上述实施方式,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也视为本发明的保护范围之内。本说明书中未作详细描述的内容属于本领域专业技术人员公知的现有技术。