framework(一)库的种类、创建、

2017-01-07  本文已影响52人  蜗牛也有梦想

编译好的二进制代码,加上头文件就能使用。可以减少项目的编译时间,只需要link一下就能够使用。不用暴露实现,只提供接口。阅读参考 iOS 静态库,动态库与 Framework

静态库、动态库产生的原因

link的方式有两种,静态、动态,由此产生了静态库和动态库。静态库在编译项目的时候会拷贝到项目中;动态库编译的时候不会被拷贝到项目中,项目中只是存储指向动态库的引用,项目运行的时候才会加载动态库。

静态库、动态库的优劣和种类

手机中可能会装很多的程序,如果同一个静态库被其中一些程序都使用了,所有这些程序都需要各自拷贝一份静态库。显然有点冗余了,而且也增加了程序在内存中的体积。但也因此程序运行的时候不用依赖外部环境。如果是很多程序都引用了同一个动态库(UIKit、Foundation),这个动态库只需要在内存中创建一份,其他使用到动态库的程序在运行的时候加载它就能够使用了,没有冗余,不影响程序的体积。但动态库会让程序依赖外部环境,也会有部分性能损失。阅读参考

静态库有两种: .a 和 .framework,其中.a是纯二进制文件,配合上一些头文件就能够使用了。.framework = .a + .h + sourceFile(.boundle)。
动态库也有两种:.framework 和 .tbd(原来是.dylib)。

Required Optional的区别

导入库的两种选择

required是加载程序的时候就加载framework,optional是加载完程序运行时调用到的时候才加载。

能打包的framework

静态库是没有限制的,但是动态库在iOS8之前是被禁止的,项目中含有动态库会被禁止上架。iOS8之后开放了动态库,但是打包的动态库无法在不同的程序之间共享,只能在项目和对应的AppExtentsion之间共享。多个程序要使用同一个动态库还是和静态库一样。阅读参考

静态库

一套属于自己的类和工具函数希望能在很多项目中被重用就是静态库的目的。静态库动态库介绍

如何创建一个静态库呢?
静态库步骤1.png

接着可以编写自己的功能,这里我创建了一个类,只有一个方法,打印日期。

步骤2.png

在Xcode 导航栏上点击小房子,选择edit Scheme 然后 选择Debug

步骤3.png

编写完成需要的代码之后,需要选择暴露那些头文件给静态库的使用者

步骤4.png

就要开始编译了,不是运行。command +b 编译。 编译的话需要编译两次,一次是模拟器一次是真机设备。编译之前 Products目录下的.a 库是红色的,编译之后会变黑色。

步骤5.png

现在静态库是可以使用了,但是分为真机和模拟器两个版本的,要是切换调试,需要手动重新导入其他的库,非常的麻烦,还好可以合并这两个.a文件为一个文件,这样只用导入一次,真机和模拟器都可以用了。
合并这两个.a文件需要用到终端。

步骤6.png

上面就是打包静态库的过程了,下面介绍静态库的使用。
先到include目录下面把需要公开的头文件拷贝到.a的路径下。然后将他们拷贝的需要使用的项目中。然后就和正常的类的使用是一样的。


拷贝文件.png

在使用静态库的时候有两点需要注意的
1.静态库包含有分类 Other Linker Flags -objC
2.静态库中全部都是分类的文件 Other Linker Flags -force

静态库包含分类的问题.png

动态库

动态库的创建

创建动态库

公开需要暴露的头文件

公开头文件

动态库静态库相互转换

静、动两种库互转

动态库的调试

动态库编写完毕之后总是会涉及到调试,可能的步骤是先修改动态库,然后编译,将编译的framework导入到测试工程中运行工程测试,然后重复这个过程。能不能边修改动态库边调试呢。步骤如下:

第一步 在新建好的动态库中添加一个app类型的target

新建调试的工程

第二步 嵌入framework

嵌入需要调试的framework

第三步 测试framwork中编写的类
在测试的工程中导入framwork中的类做调试

调试framework
2018年01月30日14:20:09

如何使用自己的framework中图片等资源?

使用framework中的图片

将CivetRTCKit.framework改为自己使用的framework 就可以了。

2017年12月20日15:29:24
framework缺少i386架构报错

这是在使用谷歌webRTC.framework的时候由于升级到了最新的版本,解决iPhoneX上视频画质有时候会出现模糊的问题遇到的新的问题。发现打包出来的framework只支持x86_64,arm64,armv7这三个架构的。
但是忽然想到之前的framework是支持四个架构的,于是突发奇想分离出旧的framework中i386架构,然后和新的framework合并。


分离framwork中某种架构的文件

根据这个还衍生出,如果在发布的时候则需要支持分离出arm64和armv7的合并这两个release版本的就可以了。

2017年07月21日22:13:21

添加framework之后,在测试project中的类中一直import不出想要的头文件,之前写的cocoapods安装中找到了答案,需要到Build Settings -> Search Paths 中找到 User Header Search Paths 中添加搜索的头文件路径。

配置自己的framework头文件搜索路径
上面的Framework Search Paths 是系统framework的头文件搜索路径,自己的framework或者其他第三方库的头文件搜索路径都要在User Header Search Paths下配置。
2017年07月21日22:20:24

dyld: Library not loaded: @rpath/ZzwTestLibrary.framework/ZzwTestLibrary Referenced from: /Users/civet/Library/Developer/CoreSimulator/Devices/51D7CD82-0CB1-4AEF-A264-9B9C80A60B67/data/Containers/Bundle/Application/0EB65D38-AB12-446F-84F3-7140ADA2A2C6/NavigationAnimation.app/NavigationAnimation Reason: image not found将动态库添加到项目中之后运行崩溃,console输出。百度到的解决办法,Embedded Binaries中添加之后,Linked Framework and Libraries 中会重复添加一份,要除掉一个。

2017年07月24日22:23:20

设置framework的版本,framework随着时间的推移,会慢慢被修改,这就需要给framework做标记来做分辨了。可以到Build Settings -> Bundle

2017年08月07日21:04:23

framwork中创建.bundle文件来包含图片、xib等资源文件。Bundle的创建Bundle加载xib异常Bundle的理解
如何一遍编写framwork一遍在项目中调试呢?参考

2017年08月23日08:14:39

全新的需求,在framework中包含其他的framework。找了很久没有比较好的,直接将需要包含的framework包含在自己的framework中,然后其他项目需要使用就只用导入一个framework。间接的解决办法framework包含静态库,大致的思想建立一个文件夹用来包含需要依赖的framework和自己打包的framework,然后其他的工程直接使用这个文件夹就可以了。

2017年08月24日08:04:22
找不到子模块警告

实际运行项目的时候不会有问题,但是总要找到警告的原因,实际上是由于在创建framework时会自动生成一个ZZW_WebRTC.h头文件用来#import此framework中需要公开的所有头文件 ,但是ZZW_Constant.h头文件并没有#import到这个这个ZZW_WebRTC.h头文件中,所以会有这个警告。

2017年09月21日14:17:04

webRTC开发的framework打包给香信的时候出现了模拟器不能运行的问题,报错的意思是framework不支持i386架构。关于CPU架构可以参考这篇文章,最新的Xcode9最低的模拟器是5s,所以是默认情况下,无法打包i386架构的framework,但是其他同事的Xcode版本比较老旧,运行的模拟器(可能是iOS系统的原因)跑不起来。
参考打包静态库这篇文章,其中第七条提到了适配所有模拟器架构Build Settings ->Architectures ->Build Active Architecture Only 改为NO就可以了。查看framework支持的架构可以使用终端命令,lipo -info .
另外需要注意的一点是,如果测试完成之后,需要上架的时候就要打包release版本的framwork。

2017年09月29日10:47:14

直接修改项目的名称带来的问题:文件读取路径错误。

plist文件路径更改 framework搜索路径更改

在项目中添加文件夹有一个技巧,可以先到项目中需要的路径下先创建好文件夹,这样framework search path 中会自动添加这个文件夹路径,再把framework拖到这个文件夹中就不必另外单独去配置framework search path了。

Bitcode的作用

在编译项目的时候遇到了bitcode的报错,因为项目导入了很多的framework,有些framework关闭了bitcode的功能,所以项目的bitcode也需要关闭才能使用这些framework。那么到底什么是bitcode呢?详情可以参考这篇文章。

bitcode功能设置
常用命令集合
name function
lipo -create path1 path2 -output path3 将path1 path2 两个文件合成为path3上的文件(path1是文件的绝对路径)
lipo -info path 查看文件支持的架构
ar -x name.a 查看静态库.a的内容
cat _.SYMDEF SORTED 查看静态库.a中链接类文件
lipo path1 -thin arm64 -output path2/-arm64 从path1路径上的framework中拆分出arm64的架构 ,放到path2路径下
lipo path1 -thin armv7 -output path2/-armv7 从path1路径上的framework中拆分出armv7的架构,放到path2路径下
lipo path1 -thin i386 -output path2/-i386 从path1路径上的framework中拆分出i386的架构,放到path2路径下
lipo path1 -thin x86_64 -output path2/-x86_64 从path1路径上的framework中拆分出x86_64的架构,放到path2路径下

参考资料
ios framework 分离与合并多种CPU架构,分离与合并模拟器与真机

上一篇下一篇

猜你喜欢

热点阅读