zoukankan      html  css  js  c++  java
  • App打包-001-静态库(.a和.framework)和动态库的区别与制作,以及使用

     

     引言

    在开发中.framework静态库还是比较常见的,我们可以把一些不愿意让别人见到的代码,用静态库的方式把它隐藏起来,只留下.h文件显示方法供编程人员使用。而.a文件出了静态库本身外,还需要引入.h文件,而.framework就不需要如此,由于.framework的方便性所以一般情况下我们见到的较多。

    库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 
    静态库:以.a.framework为文件后缀名。
    动态库:以.tbd(之前叫.dylib) 和 .framework 为文件后缀名。

    静态库可以做什么:

    1.定义基础的数据类

    2.定义视图类

    3.定义视图控制器类

    静态库与动态库的区别

    静态库和动态库是相对编译期和运行期的:

    动态库:运行时获取

    静态库:只读一次,编译时获取

    //注意:苹果禁止一切未开源的代码在APP中使用,也就是说上传APP的时候,要将代码告知给苹果,审核通过之后才能上传使用,若苹果发现上传的APP中包含静态库或者动态库则会拒绝上架。

    001-静态库.a 创建

    1.新建工程

    比如我们的工程名叫HKLibTest,那么我们创建的.a 静态库最好就是前面加个Lib,如:LibHKLibTest.a

    新建工程 (选中xcode,按commond + shift + N) 

    此时工程目录是这个样子,.a文件还没有被创建,因此是红色的 

    你可以把图中 HKLibTest.h.m 换成你自己要生成库的文件(可以是多个),在这里我就不换了,就用这两个文件,我们在.h文件中添加一个方法+sayHello,并在.m中实现它

    #import "HKLibTest.h"
    
    @implementation HKLibTest
    + (void)sayHello {
        NSLog(@".a静态库:Hello, World ~");
    }
    @end

    2.添加Headers

    按照下图顺序进行操作 

    Build Phases ->添加 -> New Run Script Phase 

     选中所有的.h文件,在点击Add

    /*
    这里需要注意的是暴露出来的头文件中import的其他类也得添加到public中暴露出来。 
    如果不想将import的类暴露出来,那么在头文件中用@class 然后在对应的.m文件中再import。 
    总之 
    1. 你再外面用到的类,一定要暴露出来; 
    2. 你暴露出来的类,头文件中导入的类也一定是暴露出来的 
    3. 如果提示导入头文件报错,找不到文件,找不到谁暴露谁就对了
    */

    3. 进行打包前的一些配置

    设置编译模式,打开xcode菜单Product -> Scheme -> Edit Scheme,改成release模式,如下图 

    编译机器的选择,如下图,一定要选择NO。(如果选择yes,生成部分机型,选择NO则适配所有机型)

    4. 接下来,我们进行打包

     操作简述: Command + B
    1. 在真机情况下编译Generic iOS Device),并记录下.a文件的绝对路径 
    2. 在模拟机情况下编译(随便吧,我用的是iPhone8Plus),并记录下.a文件绝对路径 
    3. 用命令行合并1、2部记录的文件,到新的.a文件,名字最好取开始我们取的名字吧,命令行:lipo -create 真机静态库路径空格模拟器静态库路径 -output 最终文件路径(桌面)
    4. 把你要暴露的.h文件和你已经生成的.a文件搞到一个文件夹里,这个文件夹就可以直接拖到工程里用啦

    //真机静态库路径
    /Users/MengYu/Library/Developer/Xcode/DerivedData/HKLibTest-cqiexexehimllgdmfaxigfagpzet/Build/Products/Release-iphoneos/libHKLibTest.a
    //模拟器静态库路径
    /Users/MengYu/Library/Developer/Xcode/DerivedData/HKLibTest-cqiexexehimllgdmfaxigfagpzet/Build/Products/Release-iphonesimulator/libHKLibTest.a

    合成:

    //$lipo -create /Users/MengYu/Desktop/真机静态库/libHKLibTest.a  /Users/MengYu/Desktop/模拟器静态库/libHKLibTest.a -output /Users/MengYu/Desktop/LibHKLibTest.a

    在桌面就可以看到合成之后的.a文件了

    把我们刚合成的.a文件和想暴露的.h文件,弄到一个文件夹下

    静态库创建完成~

    导入HKDemo工程中:

    #import "ViewController.h"
    #import "HKLibTest.h"
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [HKLibTest sayHello];
    }

    补充:

    查看.a文件/.Framework是否正确lipo -info

    $lipo -info 真机模式下的.a文件路径 

    /Users/MengYu/Desktop/真机静态库/libHKLibTest.a is architecture: arm64真机

    //真机 armv7 arm64 
    $lipo -info 模拟器下的.a文件路径

    /Users/MengYu/Desktop/模拟器静态库/libHKLibTest.a is architecture: x86_64模拟器

    //模拟器 i386 x86_64

    .FrameWork :

    模拟器

    //$lipo -info /Users/MengYu/Desktop/HKFrameWork.framework/HKFrameWork 
    Architectures in the fat file: /Users/MengYu/Desktop/HKFrameWork.framework/HKFrameWork are: i386 x86_64

    真机

    //$lipo -info /Users/MengYu/Desktop/HKFrameWork.framework/HKFrameWork 
    Architectures in the fat file: /Users/MengYu/Desktop/HKFrameWork.framework/HKFrameWork are: armv7 armv7s i386 x86_64 arm64 

      

    /*
    1.category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC。
    2.如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。
    */

    002-静态库.Framework创建

    1.新建工程

     这里我使用的是Xcode9,选择Cocoa Touch Framework,然后点next。

     2、创建功能类或者拖入已有的功能类,并实现功能类的功能

    3、更改Xcode项目配置

     1> Architectures 修改 BuildingSettings 添加 armv7s 

      Build Active Architecture Only 设置为NO

      

     2> Mach-O Type  设置为 Static Library 

      

     3> 添加Headers 同.a 静态库 (Build Phrases)

     4>然后需要在HKFrameworkTest.h(必须是公开的,否则无法引用)中将你所有要公开的.h引入

    4、开始打包Framework

     1>选择真机,点击Generic iOS Device Command + B 编译 ,获取真机Framework路径;

     2>选择模拟器,点击iPhone8Plus Command + B 编译 ,获取模拟器Framework路径;

     3>合成Framwork

    lipo -create 真机版本路径 模拟器版本路径 -output 合并后的文件路径/名称

    1.合并操作很容易出现问题,当提示这个错误时:

    //error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't move temporary file: /Users/xiong/Desktop/demo to file: /Users/xiong/Desktop/demo.lipo (Is a directory)

    解决方法:
    此错误一般是在合并后的路径没有加上合并后生成的文件名字,加上就行。

    2.正确:

    lipo -create /Users/MengYu/Library/Developer/Xcode/DerivedData/HKFrameWork-hfsogjyrorjfqchkyodzhhgyfwgs/Build/Products/Release-iphoneos/HKFrameWork.framework/HKFrameWork  /Users/MengYu/Library/Developer/Xcode/DerivedData/HKFrameWork-hfsogjyrorjfqchkyodzhhgyfwgs/Build/Products/Release-iphonesimulator/HKFrameWork.framework/HKFrameWork  -output /Users/MengYu/Library/Developer/Xcode/DerivedData/HKFrameWork-hfsogjyrorjfqchkyodzhhgyfwgs/Build/Products/HKFrameWork

    如图所示:

    5、将此Framework导入HKDemo工程中

    Command +B 编译一下,即可使用我们定义好的 kSCREENWIDTH

    终端版:

     //补充

    /*
    lipo -info [文件名称] :显示静态库文件的架构类型
    iphone用lipo合并模拟器库和真机库,发布一个通用的静态库
    lipo -create [文件名称1,文件名称2,.......,文件名称n] -output [生成的文件名称] 
    //静态库中是不能包含资源文件的!!!(图片,xib,音频等)
    需要资源文件的时候,生成file.bundle。
    */
    一、什么是库?
    库是共享程序代码的方式,一般分为静态库和动态库。
    
    二、静态库与动态库的区别?
    
    静态库:链接时完整地拷贝至可执行文件中,被多次使用就有多份冗余拷贝。
    动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。
    
    三、iOS里静态库形式?
    .a和.framework
    四、iOS里动态库形式?
    .dylib和.framework
    
    五、framework为什么既是静态库又是动态库?
    系统的.framework是动态库,我们自己建立的.framework是静态库。
    六、a与.framework有什么区别?
    .a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
    .a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。
    .a + .h + sourceFile = .framework。
    建议用.framework.
    
    七、为什么要使用静态库?
    方便共享代码,便于合理使用。
    实现iOS程序的模块化。可以把固定的业务模块化成静态库。
    和别人分享你的代码库,但不想让别人看到你代码的实现。
    开发第三方sdk的需要。
    
    八、制作静态库时的几点注意:
    1 注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件+.h+其它资源文件的形式,不同的是,.a本身就是二进制文件,需要我们自己配上.h和其它文件才能使用,而.framework本身已经包含了.h和其它文件,可以直接使用。
    
    2 图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。
    
    3 category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC。
    
    4 如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。

     常见问题:

    1.iOS导入动态库提示Reason:image not found

    https://www.jianshu.com/p/bed94ddacfa8

     2.ios自定义Framework 报错 Could not build module

    https://blog.csdn.net/fushi007/article/details/79420675

  • 相关阅读:
    冲刺周期第七天
    软件体系架构课下作业01
    大型网站技术架构-核心原理与案例分析-阅读笔记6
    大型网站技术架构-核心原理与案例分析-阅读笔记5
    大型网站技术架构-核心原理与案例分析-阅读笔记4
    大型网站技术架构-核心原理与案例分析-阅读笔记3
    大型网站技术架构-核心原理与案例分析-阅读笔记02
    《大型网站技术架构核心原理与案例分析》阅读笔记-01
    掌握需求过程阅读笔记—3
    掌握需求过程阅读笔记—2
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/StaticLibraryAndFrameWork.html
Copyright © 2011-2022 走看看