作者: 意一ineyee | 来源:发表于2018-10-26 16:18 被阅读11次

目录

一、库
二、静态库、动态库、Framework
三、打包静态库
 1、.a静态库和.framework静态库的区别
 2、模拟器和真机的CPU架构
 3、打包.a静态库
 4、打包.framework静态库

一、库


库其实就是一个编译好的二进制文件,我们常见的.a.dylib.framework等都是库,是代码保密和代码复用的一种方式,可以分为静态库和动态库。

二、静态库、动态库、Framework


1、静态库

静态库是指在link阶段就会被链接进可执行文件的库。

静态库的优点就在于它在link阶段就会被链接进可执行文件,因此可执行文件没有什么外部依赖,可以直接运行,运行时不会产生额外的开销。但是静态库的缺点就是会使可执行文件的体积变大。

那什么情况下我们会用到静态库呢?一种情况就是我们要把代码共享给别人使用,但是又不想让他们看到源码,就可以给他们静态库;另一种情况是我们自己要复用一些不会经常改动的代码,也可以使用静态库,这样可以减少编译时间,因为库是已经编译好了的。

静态库的存在形式有.a.framework,直接打包的静态库后缀名为.a(akynesis),用Framework打包的静态库后缀名为.framework

2、动态库

动态库则不会在link阶段被链接进可执行文件,而是在build可执行文件的时候,我们先指定可执行文件将来需要依赖哪些动态库,然后等可执行文件开始运行的时候,操作系统再把这些动态库一块加载到内存中,供可执行文件运行使用。如果多个可执行文件依赖同一个动态库,那么操作系统就只会加载一份动态库到内存中,然后把它共享给所有相关的可执行文件使用。

动态库的优点就是不影响可执行文件的体积,但是动态库动态加载的特性在运行时会造成一定的性能损耗。

那什么情况下我们会用到动态库呢?其实动态库主要就是用来供多个可执行程序共享的,但是我们知道iOS应用都是运行在沙盒中,不同的程序之间根本不能共享代码,所以咱们自己写动态库根本就不可能用到。也正因为如此,虽然我们能打包动态库,但是苹果明令禁止我们打包动态库,否则上架被拒,还是乖乖地由苹果写动态库,咱们用苹果写的就可以了。

动态库的存在形式有.dylib.framework,直接打包的动态库后缀名为.dylib(dynamic library),用Framework打包的动态库后缀名为.framework

3、Framework

Framework既可以是静态库,也可以是动态库。

三、打包静态库


因为苹果明令禁止我们打包动态库,否则上架被拒,所以接下来我们只演示静态库的打包。

1、.a静态库和.framework静态库的区别

其实不管是.a静态库还是.framework静态库,我们在供给别人使用的时候,一定是提供(二进制文件)+(.h文件)+(资源文件)三部分内容的,只不过.a静态库恰好就是这样一个模式,而.framework静态库则只有一个库,里面包含了这三部分内容而已。

.a静态库只会把代码打包进库里,不会把.h文件、资源文件(如图片、xib等)打包进库里,所以我们打包完.a静态库之后,会得到.a静态库、.h文件和资源文件三部分内容,我们还需要自己创建一个静态库文件夹来把它们打包一下再交付给别人使用。

.framework静态库会把代码、.h文件和资源文件一块打包进库里,所以我们打包完.framework静态库之后,只会得到一个.framework静态库,只不过你能看到.h文件,看不到资源文件。

.a静态库) + (.h文件) + (资源文件) = (.framework静态库)

2、模拟器和真机的CPU架构

静态库在哪种CPU架构下打包,就只支持哪种CPU架构,如果静态库不支持某种CPU架构,那么静态库在该CPU架构下是无法通过编译的。

  • 模拟器
    4S~5:i386
    5S~XS Max:x86_64

  • 真机
    3GS~4S:armv7
    5~5C:armv7s(armv7s和armv7互相兼容,静态库只要支持其中一个,在另一个架构下就能编译通过)
    5S~XS Max:arm64

3、打包.a静态库
  • 第一步:创建.a静态库工程并编写静态库代码

创建.a静态库工程,取名YYBase

创建后文件目录如下

然后编写静态库代码,比如此处在YYBase类里声明并实现一个方法用来测试

-----------YYBase.h-----------

#import <Foundation/Foundation.h>

@interface YYBase : NSObject

+ (void)test;

@end


-----------YYBase.m-----------

#import "YYBase.h"

@implementation YYBase

+ (void)test {
    
    NSLog(@"test");
}

@end
  • 第二步:配置想暴露给外界的头文件

创建一个Header Phase

创建后如下

点击加号添加想要暴露给外界的头文件

添加后如下

把头文件从Project栏拖到Public栏完成暴露

  • 第三步:配置静态库支持所有模拟器和真机的架构
  • 第四步:配置静态库为Release版本

因为静态库的主要用途是打包出来给别人或自己用的,那你给别人交付的静态库肯定不需要是Debug版啊,难不成还让别人调试吗,所以我们打包静态库要选Release版本,减少包的体积加快运行速度。

不过我们自己私下里在编写或者修改静态库的时候,可以改为Debug来调试,最后打包的时候要选Release版本。

  • 第五步:打包模拟器静态库,供模拟器使用

选中模拟器,cmd+b

.a文件变黑,说明静态库生成成功

选中.a文件,Show in Finder,文件目录如下

  • 第六步:打包真机静态库,供真机使用

选中Generic iOS Device或插入真机选中,cmd+b

.a文件变黑,说明静态库生成成功

选中.a文件,Show in Finder,文件目录如下

  • 第七步:合并模拟器静态库和真机静态库,模拟器和真机都能使用

需要用终端合并,命令格式为:lipo -create 真机.a文件路径 模拟器.a文件路径 -output 合并后的.a文件路径

打开终端,输入下面的指令:

lipo -create /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/Release-iphoneos/libYYBase.a /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/Release-iphonesimulator/libYYBase.a -output /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/libYYBase.a

合并成功后就会发现文件目录里确实多出来一个合并后的.a文件

此时我们可以在终端通过lipo -info 静态库.a文件的路径指令来查看下它所支持的架构。

打开终端,输入下面的指令:

lipo -info /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/libYYBase.a

命令执行后,我们发现该静态库支持armv7 i386 x86_64 arm64模拟器和真机的四种架构

Architectures in the fat file: /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/libYYBase.a are: armv7 i386 x86_64 arm64

  • 第八步:创建一个静态库文件夹打包.a静态库和.h文件共外界使用

这个时候我们需要创建一个静态库文件夹,把合并后的.a静态库和随便一个user下的include文件拖进我们自己创的文件夹里,然后交给别人使用就可以了。

比如,我们现在有一个Test项目,引入了我们的静态库后,可以正常使用

  • 第九步:那我们怎么把图片等资源打包进.a静态库呢,以图片为例

比如现在,我们要给libYYBase静态库新增了一个读取图片的功能。

新建一个文件夹后缀名改为.bundle,名字按自己的需求取,把静态库里用到的图片放进去,拖进静态库工程里,新增后目录如下

然后为静态库新增读取图片的代码

-----------YYBase.h-----------

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface YYBase : NSObject

+ (void)test;
+ (UIImage *)readImage;

@end


-----------YYBase.m-----------

#import "YYBase.h"

@implementation YYBase

+ (void)test {
    
    NSLog(@"test");
}

+ (UIImage *)readImage {
    
    NSString *resourceBundlePath = [[NSBundle mainBundle] pathForResource:@"Resource" ofType:@"bundle"];
    NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
    
    NSString *imagePath = [resourceBundle pathForResource:@"testImage" ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    
    return image;
}

@end

cmd+b,生成新的静态库,然后把新静态库、.h文件和资源文件一块放在静态库文件夹内,交付给外界。

比如,现在Test项目就会变成这样

4、打包.framework静态库

其实和打包.a静态库基本上一模一样。

第一步:创建一个.framework工程并编写静态库代码

创建.framework新工程,取名YYBase

创建后文件目录如下,自带的头文件用来让我们把静态库里所有要公开的头文件都在这里引入

然后编写静态库的代码,比如此处创建一个YYTest类里声明并实现一个方法用来测试

-----------YYTest.h-----------

#import <Foundation/Foundation.h>

@interface YYTest : NSObject

+ (void)test;

@end


-----------YYTest.m-----------

#import "YYTest.h"

@implementation YYTest

+ (void)test {
    
    NSLog(@"test");
}

@end
  • 第二步:配置framework打包静态库

因为framework既可以打包静态库也可以打包动态库,而且默认是打包动态库,所以我们要配置它打包静态库。

  • 第三步:配置想暴露给外界的头文件


  • 第四步:配置静态库支持所有模拟器和真机的架构

  • 第五步:配置静态库为Release版本
  • 第六步:打包模拟器静态库,供模拟器使用

选中模拟器,cmd+b

. framework文件变黑,说明静态库生成成功

选中. framework文件,Show in Finder,文件目录如下

  • 第七步:打包真机静态库,供真机使用

选中Generic iOS Device或插入真机选中,cmd+b

. framework文件变黑,说明静态库生成成功

选中. framework文件,Show in Finder,文件目录如下

  • 第八步:合并模拟器静态库和真机静态库,模拟器和真机都能使用

需要用终端合并,命令格式为:lipo -create 真机文件路径 模拟器文件路径 -output 真机文件路径

命令还是一样的命令,只不过framework不是直接合并framework,而是其下的文件

打开终端,输入下面的指令

lipo -create /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/Release-iphonesimulator/YYBase.framework/YYBase /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/Release-iphoneos/YYBase.framework/YYBase -output /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/YYBase.framework/YYBase

合并成功后会替换掉真机原来的文件,我们直接用真机的这份framework就行了,它已经兼容真机和模拟器的版本了

此时我们可以在终端通过lipo -info 静态库.a文件的路径来查看下它所支持的架构

lipo -info /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/Release-iphoneos/YYBase.framework/YYBase

命令执行后,我们发现该静态库支持armv7 i386 x86_64 arm64模拟器和真机的四种架构

Architectures in the fat file: /Users/yiyi/Library/Developer/Xcode/DerivedData/YYBase-aktvhdicknregncrbwimaxlucgvc/Build/Products/Release-iphoneos/YYBase.framework/YYBase are: i386 armv7 x86_64 arm64

  • 第九步:用framework打出来的静态库我们不需要自己创建静态库文件夹,直接把.framework静态库供给外界使用就可以了

比如,我们现在有一个Test项目,引入了我们的静态库后,可以正常使用

  • 第十步:那我们怎么把图片等资源打包进.framework静态库呢,以图片为例

其实和上面.a的差不多,直接把放好图片的.bundle文件拖进去,编写新的静态库代码,需要注意读取资源的时候和上面.a不太一样了,路径需要加上你的framework

+ (UIImage *)readImage {

    NSString *resourceBundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"YYBase.framework/Resource.bundle"];
    NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
    
    NSString *imagePath = [resourceBundle pathForResource:@"testImage" ofType:@"png"];
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    
    return image;
}

cmd+b重新生成一下静态库,然后把新静态库拖进测试项目中,此时需要多一步,要不然资源文件读取不到


参考博客:

iOS库 .a与.framework区别
ios打包静态库,看这篇就够了
绝对手把手教你如何将一整个xcode工程打包成静态库


相关文章

  • 公司数据库逻辑

    pro库 drds库 通道库 查询库 pg库 bi库 tidb库 odps查询 pro库和drds库是线上数据库 ...

  • Lua库函数概览

    Lua库函数概览数学库 table库 字符串库 IO库 os库 调试库

  • Swift 静态库调研

    一、关于库的背景知识1、静态库和动态库静态库动态库系统动态库Cocoa Touch Framework静态库 v....

  • iOS 创建静态库(.a)

    静态库(.a) 文章类型: 学习笔记 1. 静态库简介 库的概念: 什么是库? 库的分类: 库的存在形式: 静态库...

  • 目录一、库二、静态库、动态库、Framework三、打包静态库 1、.a静态库和.framework静态库的区别 ...

  • iOS 静态库和动态库的制作

    静态库和动态库 一、静态库和动态库的存在形式 静态库: .a 和 .framework 动态库: .dylib 和...

  • 动态库与静态库相互连接

    动态库--动态库 场景:App --> 动态库A --> 动态库 B 存在问题:动态库B应该的路径 = 动态库A的...

  • Python解析库

    Python解析库 目录一、lxml库二、BeautifulSoup库三、PyQuery库 一、lxml库 教程:...

  • HCMediator组件化详解

    组件化创建流程库 组件化需要创建私有spec库(索引库)、HCMediator库(App中介库)、其他组件库 私有...

  • iOS静态库和动态库浅析

    一、库 库是共享程序代码的方式,一般分为静态库和动态库。 二、静态库和动态库 静态库形式:.a和.framewor...

网友评论

      本文标题:

      本文链接:https://www.haomeiwen.com/subject/ijrubftx.html