前言
•本文属于iOS开发基础内容,主要讲述了静态库的生成和项目间互相调用的场景。 属于模块化开发的基础。
用途:实现代码组件复用,有效模块化管理各个静态库!!
本文学习过程
1.框架简述
2.从零开始创建静态库 ;
3.在已有项目中创建项目静态库;
4.静态库的使用方式;
1.框架简述
框架是一个封装共享资源的层次目录,如动态共享库、nib文件、图像文件、本地化字符串、头文件和单个包中的参考文档。多个应用程序可以同时使用所有这些资源。系统根据需要将它们加载到内存中,并尽可能地在所有应用程序之间共享资源的一个副本。
库和框架默认是必需的,但可以将此指定更改为可选的。必须(required)库必须存在于项目供产品加载。可选(optional)库不必存在供产品加载。必须(required)库将始终加载到内存中,但可选(optional)库只在需要时才加载。如果一个大库不需要加载被指定为可选的,则应用程序的初始加载会快一点。
iOS不允许进程间共享动态库,iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。
我平时使用的都是静态库,以下讲述静态库的使用。
2.从零开始创建静态库
1.xCode创建库项目
创建成功后,项目少了appdelegate相关文件,主要有一个heaher文件
header文件用于用户开放框架内部的接口声明
2.给框架创建工具类
库内新创建的文件会自动自定Target,不需要手动设置
在这种方式下,只需要做2个操作,就完成需要的库:
1.在build Phases里,将需要开放他头文件设置到public
2.将开放的头文件写入framework的头文件
至此,打包的静态库已经可以打包使用了!
这种方式的过程中,可以使用模块测试方式对模块进行测试,也可以嵌套到demo项目中验证模块,另一种方式,一般生成项目(例如Demo),直接将项目部分核心文件打成框架会比较直观,以下讲解,在项目种创建静态库
3.在已有项目中创建项目静态库
很多时候,我们开发项目过程中,有些组件(如网络层,UI组件,工具类,音视频管理类,地址类,Socket等通讯类)是可以复用的,或者,我们在开发的过程中,某一模块值得构建成框架,我们都可以在当前项目中,切出框架出来。
以下是简单的步骤演示:
1.创建framework的target,在项目的general栏,点击左下角的“+”号(或者File-》New-》Target),选择Framework,设置里可以Embed in Application先选择 None,然后点击生成,你会发现Target里多了一个framework,创建完毕。
2.将框架需要的类指定Target到framework,本例应该将红框内所有的文件指定Target中GoodProjectFW打钩
3.将头文件写入GoodProjectFW的头文件里,并且在Target栏里点击GoodProjectFW,然后选择build Phases,在build Phase里将需要开发的头文件,移到public group里。(这里和新建FW的操作一样)
选择FW的Target,选择Generic iOS Device 运行一下,在products文件夹里就会有个framework文件生成(从红变黑),这个就是我们打包好的Framework。
4.静态库的使用方式
不带源码方式(将framework文件合并(合并步骤请搜索大牛文章)提供给别人,框架导入项目使用,或者cocoapods)&&带源码方式(用得多,自己开发项目,不同项目可能要稍作修改兼容,调试方便)
以下主要讲带源码方式的过程:
静态库的使用情况:1.workspace 2. 直接添加至项目内
两种场景使用的区别,目前发现是:workspace不需要框架文件在当前开发项目内,另一方面,直接添加至项目内的,则需要将框架文件放进当前开发项目,其它步骤一样。
1.使用workspace方式(带源码)
将两个APP项目添加到workspace里面去(也可是是一个APP项目,一个框架项目)
使用直接导入项目方式(带源码)
2.设置Link Binary With Libraries
3.导入框架头文件,调用资源,Nib文件,模块方法等
#import <GoodProjectFW/GoodProjectFW.h> @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSBundle *bundle = [NSBundle bundleForClass:[demoViewViewController class]]; UIImage *image = [UIImage imageNamed:@"qq" inBundle:bundle compatibleWithTraitCollection:nil]; UIImageView *imgV = [[UIImageView alloc] initWithImage:image]; imgV.frame = CGRectMake(0, 0, 100, 100); imgV.backgroundColor = [UIColor yellowColor]; [self.view addSubview:imgV]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(100, 200, 120, 30); button.backgroundColor = [UIColor blueColor]; [button addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; } - (void)btnClick:(UIButton *)btn{ NSBundle *bundle = [NSBundle bundleForClass:[demoViewViewController class]]; demoViewViewController *frameworkVC = [[demoViewViewController alloc] initWithNibName:@"demoViewViewController" bundle:bundle]; [self presentViewController:frameworkVC animated:YES completion:^{ }]; [goodTool tools]; }
注意调用资源和XIB和平时不一样,请仔细查看上面的代码!
到这里就不再累赘了!!!相信小伙伴们已经能大概了解静态库的生成和使用。。
疑问
在写demo的过程中,有个疑惑,如果框架里面的类,项目里面也有,方法相同会怎么样,方法不相同会怎么样?如果这情况发生在两个不同的框架呢?
经过检验,如果当前项目已经有此这个类,以当前类为主,框架里的类+load方法也会被调用,但仿佛被覆盖了。此时,如果调用的方法不存在于当前项目类(尽管存在框架里),项目会奔溃。不同的框架以最后添加的框架为主!所以,注意框架内文件的命名。
总结
本文简单地记录了静态库生成的两种方式,然后描述了静态库的使用场景!!这些操作,常用于项目间代码模块复用,好处是,多人合作项目时,项目能进行模块分工,而且模块清晰便于后期维护,也提高了项目模块功能增删的效率!!