ios下动态加载系统库文件的方法

2015-02-27 07:29:36胡必玲郭玉堂叶嘉桓
合肥师范学院学报 2015年6期

胡必玲,郭玉堂,叶嘉桓

(1. 合肥师范学院计算机学院,安徽 合肥 230601;2.友盟科技有限公司,北京 200000)



ios下动态加载系统库文件的方法

胡必玲1,郭玉堂1,叶嘉桓2

(1. 合肥师范学院计算机学院,安徽 合肥 230601;2.友盟科技有限公司,北京 200000)

[摘要]针对现有的集成第三方SDK需要的系统库文件方法效率低下问题,提出了一种集成系统库文件的新方法,该方法能动态加载第三方SDK需要的系统库文件,用程序的方式加载系统库文件来代替手工添加,简化了集成系统库文件的步骤,可以节约开发时间和成本。

[关键词]库文件;第三方SDK;动态加载

随着计算机通信技术的发展,使用iOS(iphone operating system)系统的移动终端受到了许多用户的喜欢,基于iOS开发的应用程序也越来越多。开发者在开发应用程序的过程中,为了提高开发效率,实现更多应用功能,增强用户体验,普遍要使用第三方SDK(Software Development Kit,软件开发工具包)。开发者在使用第三方SDK时,需要添加第三方SDK需要的系统库文件到自己的应用开发工程中,然后在应用开发工程对应的应用程序的Load Librarys(加载库)阶段,加载第三方SDK需要的系统库文件和应用程序本身需要的系统库文件,实现对第三方SDK需要的系统库文件的集成。

现有的对系统库文件的集成方法需要开发者读取第三方SDK的添加说明,将第三方SDK需要的系统库文件,手动添加在应用开发工程Xcode的库文件列表中,在Load Librarys阶段进行加载,如,如果要使用分享到手机QQ或者登录QQ账号的功能,需要使用QQ互联提供的SDK,就需在Xcode中添加”Security.framework” 、”libiconv.dylib”、 ”SystemConfiguration.framework”等八个系统库文件。上述集成过程繁琐,浪费时间,成本高。本文提出的动态加载技术,可以自动加载第三方SDK需要的系统库文件,开发者在使用第三方SDK时,不需要知道第三方SDK内部调用了哪些系统库文件,不需要手动添加第三方SDK需要的系统库文件,简化了集成系统库文件的步骤,可以节约时间和成本。

1方法原理

一般开发者在集成第三方SDK需要下面的步骤,参考图1

图1 开发者集成SDK的步骤

本文提出的动态添加系统库文件的方法,可以减少开发者添加系统库文件的步骤,提高开发效率。

主要原理是用程序的方式加载系统库文件来代替手工添加系统库文件。在程序启动之后,在执行主函数之前,在类的构造函数阶段加载所述应用程序本身需要的系统库文件;在程序的编译阶段使用objective-c语言的动态特性,来实现在没有头文件情况下通过程序的编译。

2方法实现

使用代码取代手工来加载库文件到工程,即所谓动态加载的方式,主要要解决两个问题:

(1)程序运行阶段可以执行该库文件提供的接口。

(2)程序编译阶段可以通过编译器的检查,正常编译。

2.1解决运行时问题

解决第一个问题,由于iOS系统本身就会把所有系统库文件加载到系统级内存空间,应用程序只需要实现把所需要的系统库文件从系统内存加载到应用级内存即可。

加载系统库文件到应用级内存,需要在应用启动之后立即把系统库文件加载到内存。

图2为iOS系统的启动流程,加载库文件后,会执行类初始化方法,即__attribute__((contructor))方法内的代码,然后才会执行main()主函数。

为了确保在所有运行SDK逻辑代码前载入系统framework。将动态载入framework的方法放在__attribute__((contructor))方法内,确保在所有方法执行前已经加载framework成功。使用NSBundle类,用各个系统framework路径生成NSBundle对象,用load方法加载到应用。

例如要加入QuartzCore.framework到系统工程,可以利用下面的代码来实现:

NSBundle *quartzCoreSupportBundle = [NSBundle bundleWithPath:@"/System/Library/Frameworks/QuartzCore.framework"];

if (quartzCoreSupportBundle != nil)

{

[quartzCoreSupportBundle load];

}

else

{

NSLog(@"Load QuartzCore framework fail!");

}

这样就能解决程序运行阶段使用库文件的问题。

2.2解决编译时问题

由于SDK需要依赖调用的系统framework(包括系统库文件和系统头文件)是通过在运行时动态加载的方式来实现,而在静态编译阶段是没有加入到库文件的,编译阶段也没有加入framework的头文件到工程。所以在源代码也不能引用系统framework的定义的头文件,若直接声明使用该framework定义的类,就会出现源代码在预编译阶段编译器就会有报错,而不通过编译。

解决方法可以利用Objective-C语言的动态特性,方法如下:

a) 所有需要用引用的系统framework下面的类,都使用下面的动态方法的方式来初始化对象

NSClassFromString(“ClassName”)

b) 使用动态调用的方式来执行相应的方法:

[object performSelector:@selector(selectorName)]

通过这些方法就可以实现,不引用系统framework的头文件下,又能使用framework下的类和调用相应的方法的目的。

例如,如果正常方式下对AvAudioPlayer进行初始化,需要先引用该头文件:

#import

AVAudioPlayer * player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL URLWithString:path] error:nil];

可是使用本论文动态加载库文件的方法,是不能引用该系统头文件的,为了达到通过编译的目的,可以用下面的代码来实现:

idplayer = [[NSClassFromString(@"AVAudioPlayer") alloc] performSelector:@selector(initWithContentsOfURL:error: withObject:[NSURL URLWithString:path] withObject:nil);

图2 iOS系统的启动流程

3方法效果分析

经过运行分析,对比使用本方法和使用传统的方法加载系统库文件在运行时间上没有任何区别,表1是统计同一个应用程序分别使用这两种技术的系统启动时间。对比传统的加入库文件方法,使用本方法的SDK可以节约开发者的开发时间,减少开发者错误。

据第三方平台统计,国内市场上有677个为开发者服务的产品,包括推送、地图、社交分享、即时通讯、游戏引擎、语音等等。所有产品都包括有安卓和iOS这两个主流移动系统平台,每二个iOS开发者平均会使用5~6个第三方SDK来进行应用开发。

表1 新方法和传统方法的对比

4结语

本文介绍了一种在iOS平台下可以自动加载系统库文件的方法,方法使用简单,容易推广,并且能够为使用该SDK进行开发的开发人员节省大量开发时间。

[参考文献]

[1]devstore全球首家开发者服务商店 http://www.devstore.cn.

[2]iOS程序完整启动过程及原理 http://bbs.csdn.net/topics/390714823.

[3]2014年开发者服务市场占有率报告 http://www.devstore.cn/new/newInfo/1209.html.

[4]苹果官方文档 objective-c介绍.https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html.

[5]苹果官方文档 iOS系统介绍.https://developer.apple.com/library/ios/documentation/Miscellaneous/Conceptual/iPhoneOSTechOverview/Introduction/Introduction.html.

A Method of Integrating System Library Files

HU Biling1, GUO Yutang1, YE Jiahuan2

((1.SchoolofComputerScience,HefeiNormalUniversity,Hefei230601,China;

2.UmengTechnologyCompany,Ltd.Beijing200000 ,China)

Abstract:As the current method of integrating the third party SDK's system library files is low efficient , the paper proposes a new method integrating system library files, which can dynamically load system library files of the third-party SDK needed instead of manual addition. This method simplifies the steps of integrating system library files, which can save the time and cost of its development.

Key words:system library files; the third-party SDK; dynamic loads

[中图分类号]TP319

[文献标识码]A

[文章编号]1674-2273(2015)06-0059-03

作者简介][第一 胡必玲(1985- ),女,助教,硕士,主要研究领域:无线传感网,嵌入式系统。

[基金项目]安徽省高校自然科学基金重点项目(KJ2013A217)

[收稿日期]2015-01-18