iOS 静态库制作(Xcode9.0)

首语:生命不息,学习不止

在实际开发过程中,我们或许会涉及到各种不同的协作开发形式,或许也有将自己封装的类运用到其它 app 的情况,在这个时候,如果单纯的使用 crtl+c、ctrl+v ,或许使得项目变得不容易维护,整洁性,还有封装性大大降低,这个时候,我们需要库的支持。

基本知识:

1. 库类别
  • 静态库(.a 和.framework)
  • 动态库(.liby和.framework)
2.静态库和动态库的区别

2.1静态库

  • 平时我们用的第三方SDK基本上都是静态库。
  • 静态库在项目编译时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。
  • 静态库很大的一个优点是减少耦合性,因为静态库中是不可以包含其他静态库的,使用的时候要另外导入它的依赖库,最大限度的保证了每一个静态库都是独立的,不会重复引用。
  • 静态库有.a 和 .framework两种形式。

2.2动态库

  • iOS平时使用的系统库基本是动态库,比如使用频率最高的UIKit.framework和Fundation.framework。
  • 动态库在程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。
  • 动态库在制作的时候可以直接包含静态库,也能自动link所需要的依赖库。
  • 动态库有.dylib/.tbd 、.framework两种形式。
  • 苹果禁止iOS开发中使用动态库
3.版本
  • 真机-Debug版本
  • 真机-Release版本
  • 模拟器-Debug版本
  • 模拟器-Release版本

区别

3.1 Debug

  • 含完整的符号信息,以方便调试
  • 不会对代码进行优化

3.2 Release

  • 不会包含完整的符号信息
  • 的执行代码是进行过优化的
  • 的大小会比Debug版本的略小
  • 在执行速度方面,Release版本会更快些(但不意味着会有显著的提升)

基本操作:.a静态库制作

环境
Xcode9.1
iTerm终端

1. 新建静态库工程

Create a New Xcode project -> Framework&Library -> Cocoa Touch Static Library
这里写图片描述

文件结构如下:

这里写图片描述

2. 配置工程环境

2.1配置最低支持版本

这里写图片描述

2.2设置适配所有模拟器架构重要

project -> buildSeting -> Build Active Architecture Only 设为NO

这里写图片描述

3. 新建公开的文件

3.1新建一个名为“testTool 文件” 公开一个方法“testLog”

这里写图片描述

这里写图片描述

3.2添加公开文件

3.2.1 点击“+” 新增”Header Phase”

这里写图片描述

3.2.2 添加文件到 project

这里写图片描述

3.2.3 拖拽.h到 public

这里写图片描述

最终结果如下:

这里写图片描述

4. 生成.a文件

此处注意需要生成4个

4.1修改环境

这里写图片描述

这里可以选择 Debug 和 Release 环境

这里写图片描述

4.2选择模拟器+Debug 环境+“cmd+R”生成.a

这里写图片描述

此处注意需要生成4个
如此类推打出四种.a

  • 真机-Debug版本
  • 真机-Release版本
  • 模拟器-Debug版本
  • 模拟器-Release版本

最终生成结果
这里写图片描述

4.3合并 debug 两个包和 release 两个包

注意:这里的合并指的是 1.debug 下真机+模拟器合并 2.release 下真机+模拟器合并

4.3.1将4个.a文件拷贝到单独文件夹

这里写图片描述

4.3.2 合并

打开终端
命令规则

lipo -create+空格+模拟器Debug路径+空格+模拟器Release路径+空格-output+空格+输出路径+输出名字(可自定义)

例如:
lipo -create /Users/fujia/Desktop/a/libStaticWork-Debug-iphoneos.a /Users/fujia/Desktop/a/libStaticWork-Debug-iphonesimulator.a -output /Users/fujia/Desktop/a/libStaticWork-Debug.a

这里写图片描述

标注出是自己起名

同理 release 也是如此 最后生成两个文件

这里写图片描述

5.使用方法

5.1新建一个新工程
**5.2引入文件
5.2.1引入libStaticWork-Debug.a和libStaticWork-Release.a

5.2.2引入 include 文件
在之前的静态库文件找到任意的生成文件 引入 include 文件

这里写图片描述

最后引入结果如下

5.3调用以及结果

这里写图片描述

基本操作:.framework静态库制作

1.新建 framework 工程

这里写图片描述

2.新建文件类

这里写图片描述

3.修改工程文件配置

build setting ->搜索 mach -> 修改 mach -O Type ->static Library

这里写图片描述

这里写图片描述

4.引入其他第三方库(如果有的话)

⚠️注意:导入第三方静态库的时候不要选择添加到target中

这里写图片描述

5.暴露头文件

拖拽文件到这里

这里写图片描述

6.生成 .framework

6.1修改环境

这里写图片描述

这里可以选择 Debug 和 Release 环境

这里写图片描述

6.2选择模拟器+Debug 环境+“cmd+R”生成.a

这里写图片描述

此处注意需要生成4个
如此类推打出四种.a

  • 真机-Debug版本
  • 真机-Release版本
  • 模拟器-Debug版本
  • 模拟器-Release版本

最终生成结果

这里写图片描述

7.合并 debug 两个包和 release 两个包

注意:这里的合并指的是 1.debug 下真机+模拟器合并 2.release 下真机+模拟器合并

7.1将4个.a文件拷贝到单独文件夹

这里写图片描述

7.2 合并

打开终端
命令规则

lipo -create+空格+模拟器Debug路径+空格+模拟器Release路径+空格-output+空格+输出路径+输出名字(可自定义)

例如:
lipo -create /Users/fujia/Desktop/framework/StaticFramework-Release-iphoneos /Users/fujia/Desktop/framework/StaticFramework-Release-iphonesimulator -output /Users/fujia/Desktop/framework/StaticFramework-Release

这里写图片描述

标注出是自己起名

同理 release 也是如此 最后生成两个文件

这里写图片描述

**7.3替换文件
7.3.1寻找之前生成的 任意framework
**7.3.2替换二进制文件

替换前

这里写图片描述

替换后

这里写图片描述

8.使用方法
8.1新建工程
8.2应用 framework
8.3结果如下

这里写图片描述

9.注意的地方

9.1警告
如果我们什么都不配置的话 应用 framework 里面的文件 会产生如下的警告
missing submodule ‘StaticFramework.framewokrTool”

这里写图片描述

解决方案:
在 framework 的头文件也就是创建 framework 时同名的.h里面引入我们的头文件

这里写图片描述

就可以了

9.2资源文件 .bundle

静态库中有使用到图片、音视频等资源文件,可以将这些文件打包成.bundle文件供静态库使用。

最简单的方法是,新建一个文件夹,将图片、音视频等资源拖到文件夹中,将文件夹后缀名改为.bundle.
静态库想要使用里面的资源的话需要先获取到该.bundle文件。

NSBundle *bundle = [NSBundle bundleWithPath: [[NSBundle mainBundle] pathForResource:@"BundleName" ofType: @"bundle"]];

静态库中使用.bundle文件里面的图片的方法是:

NSString *imageName = [[bundle resourcePath] stringByAppendingPathComponent:assetName];
[_imageView setImage:[UIImage imageWithContentsOfFile:imageName]];

⚠️注意:.bundle文件无法封装到framework里,需要将.framework,.bundle同时导入项目中才能正常使用

9.3使用category

在制作framework的时候,如果使用了category,则使用该framework的项目运行时会crash,此时需要在该工程中 other linker flags添加一个参数 -ObjC

这里写图片描述

参数说明

  • ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中

  • all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。

  • force_load:所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载

总结:
在实际制作过程中,总是会遇见各种各样的问题,这个时候需要借助搜索,查阅资料等来解决这个问题,静下心来,减少错误。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值