在日常项目开发中,不论是为了两个公司项目上的业务交流还是为了减少项目的编译时间,有的时候我们会把项目中的私密内容打包成静态库,或者是把项目中变动较少一部分打包成静态库以便提高编译效率,那么下面我们就来学习一下"iOS-静态库的创建与使用":

(一)iOS静态库、动态库与Framework静态库与动态库的区别

(1)什么是库?

库(Library)直白一点说就是一段编译好的二进制代码,加上头文件就可以供别人使用;(例如: iOS中Objective-C编译下的.h和.m文件,打包静态库后会变为.h和.a文件);

(2)什么是静态库?

①静态库即静态链接库(例如: windows下的.lib、Mac和Linux下的.a);

②静态库在编译的时候会被直接拷贝一份,复制到目标程序里并且这段代码在目标程序里就不会在改变了,我猜这也是该库叫"静态库"的原因;

③静态库的利弊:

1)利: 静态库在编译完成之后,库文件实际上就没有作用了,目标程序没有外部依赖,直接就可以运行;

2)弊: 弊端静态库会使用目标程序的体积增大;

(3)什么是动态库?

①动态库即动态链接库(例如: windows下的.dll、Mac下的.dylib、Linux下的.so);

②与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用,等到程序运行时,动态库才会被真正加载进来;

③动态库的利弊:

1)利:不需要拷贝到目标程序中,不会影响目标程序的体积,而且同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库);同时,编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码;

2)弊:动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境;如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行;

(4)什么时候我们会用到库呢?

①某些代码片段需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件;

②对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间;

说明:上面提到库在使用的时候需要Link,Link 的方式有两种:静态和动态,于是便产生了静态库和动态库("攻城狮"的思维就是这么简单);

(5)iOS Framework?

①除了上面我们提到iOS的.a和.dylib之外,Mac OS/iOS 平台还可以使用 Framework,Framework实际上是一种打包方式,将库的二进制文件、头文件和有关的资源文件打包到一起,方便管理和分发;在 iOS 8 之前,iOS 平台不支持使用动态 Framework,开发者可以使用的 Framework 只有苹果自家的 UIKit.Framework,Foundation.Framework 等等;

②上面这种限制可能是出于安全的考虑,换一个角度讲,因为 iOS 应用都是运行在沙盒当中,不同的程序之间不能共享代码,同时动态下载代码又是被苹果明令禁止的,没办法发挥出动态库的优势,实际上动态库也就没有存在的必要了;

③由于上面提到的限制,开发者想要在 iOS 平台共享代码,唯一的选择就是打包成静态库 .a 文件,同时附上头文件;但是这样的打包方式不够方便,使用时也比较麻烦,大家还是希望共享代码都能能像 Framework 一样,直接扔到工程里就可以用;

④终于在日思夜盼便迎来了iOS对动态库的支持:iOS 8/Xcode 6 推出之后,iOS 平台添加了动态库的支持,同时 Xcode 6 也原生自带了 Framework 支持(动态和静态都可以);

⑤但是说道这里博主要告诉一下大家,iOS动态库且用且珍惜(小心应用审核被拒😄😄);

(二)切入主题"iOS静态库的创建":

(1)我们先了解静态库文件的版本(四种):

①真机-Debug版本;  ②真机-Release版本  ③模拟器-Debug版本  ④模拟器-Release版本;

(2)Debug(调试)版本特点:

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

(3)Release(发布)版本特点:

①不会包含完整的符号信息;  ②执行代码是进行过优化的;  ③大小会比Debug版本的略小  ④在执行速度方面,Release版本会快一些;

所以我们一般开发中都打包Release(发布)版本使用;

(4)再来了解一下iPhone设备CPU的架构简介:

①模拟器:(4s~5: i386)    (5s~6splus: x86_64)

②真 机: (3gs~4s: armv7)  (5~5c: armv7s)     (5s~6splus: arm64)[说明: 静态库只要支持了armv7,就可以跑在armv7s的架构上];

(三)制作静态库-Debug版本:

(1)创建Cocoa Touch Static Library,新建项目选择iOS ->Framework&Library ->Cocoa Touch Static Library,如图1:

(2)点击Next给工程命名如"Library"点击Next,Xcode自动为我们创建了Library.h/.m文件以及相对应的目录结构,如图2所示:

    

(3)接下来我们在工程的.h和.m里面编写功能实现的代码(重在静态库的创建, 代码粗略请大家无视😄😄):

"Library.h"
/** 十六进制转二进制 */
  (NSString *)getBinaryByhex:(NSString *)hex;

"Library.m"
  (NSString *)getBinaryByhex:(NSString *)hex {
  NSMutableDictionary *hexDic = [[NSMutableDictionary alloc] init];
  
  hexDic = [[NSMutableDictionary alloc] initWithCapacity:16];
  [hexDic setObject:@"0000" forKey:@"0"];
  [hexDic setObject:@"0001" forKey:@"1"];
  [hexDic setObject:@"0010" forKey:@"2"];
  [hexDic setObject:@"0011" forKey:@"3"];
  [hexDic setObject:@"0100" forKey:@"4"];
  [hexDic setObject:@"0101" forKey:@"5"];
  [hexDic setObject:@"0110" forKey:@"6"];
  [hexDic setObject:@"0111" forKey:@"7"];
  [hexDic setObject:@"1000" forKey:@"8"];
  [hexDic setObject:@"1001" forKey:@"9"];
  [hexDic setObject:@"1010" forKey:@"A"];
  [hexDic setObject:@"1011" forKey:@"B"];
  [hexDic setObject:@"1100" forKey:@"C"];
  [hexDic setObject:@"1101" forKey:@"D"];
  [hexDic setObject:@"1110" forKey:@"E"];
  [hexDic setObject:@"1111" forKey:@"F"];
  
  NSString *binaryString=[[NSMutableString alloc] init];
  
  for (int i=0; i<[hex length]; i  ) {
    NSRange rage;
    rage.length = 1;
    rage.location = i;
    NSString *key = [hex substringWithRange:rage];
    binaryString = [NSString stringWithFormat:@"%@%@",binaryString,[NSString stringWithFormat:@"%@",[hexDic objectForKey:key]]];
  }
  return binaryString;
}

(4)编译项目生成对应的静态库.a文件(在这里注意一下细节):

①在工程编译(Command B)之前"标号为②的框框中libLibrary.a"为红色(编译之后为黑色, 红色表示一个虚拟的文件工程中找不到它),如图3所示:

      

②编译的过程中我们要选择"模拟器编译"和"真机编译",如图4图5所示:

      

(5)右击工程目录下.a文件,查看编译之后的静态库文件如图6所示, 其中文件Debug-iphoneos里面包含iPhone真机所需要的libLibrary.a静态库文件,文件Debug-iphonesimulator里面包含的时iPhone模拟器所需要的libLibrary.a静态库文件,如图7所示;

    

(6)分别查看打包好的模拟器与真机的静态库所支持的cpu架构:

在上面我们介绍了iPhone设备CPU的架构,在这里我们就来查看我们所打包的静态库是否符合iPhone设备包含的架构标准(提示: 如果不符合某些架构的标准,静态库运行到不同机型上回报错误),打开终端查看静态库的架构如图8所示:

我们找到原因如图9所示,下面Debug:Yes表示只编译选中模拟器对应的架构,No则为编译所有模拟器支持的cup架构(Debug的Yes状态改为No即可);

    

再一次Command B 编译重复上面第(4)步的小步骤,就OK了,😄😄...

(7)合并静态库:

①为什么要合并静态库呢?

因为真机和模拟器的静态库,是不一样的,不能同时适用在真机和模拟器上,但要满足这要求的话,要对编译好的两个静态库进行合并在使用;

②合并静态库的利弊?

1)利:开发过程中既可以在真机上调试,也可以在模拟器上调试;

2)弊:如果静态库太大,合并打包后,会非常大,因此很多第三方的静态库的.a是区分版本的;

③打开终端合并静态库(终于快成功了😄😄...)如图10所示:

      

其中完整的命令是:

lipo -create /Users/apple/Library/Developer/Xcode/DerivedData/Library-bmlhmlslupltsqfkcfgmgqzducdy/Build/Products/Debug-iphoneos/libLibrary.a /Users/apple/Library/Developer/Xcode/DerivedData/Library-bmlhmlslupltsqfkcfgmgqzducdy/Build/Products/Debug-iphonesimulator/libLibrary.a -output /Users/apple/Desktop/libLibrary.a;

(8)静态库的使用:

将合并好的静态库文件(.a)和头文件(.h)添加到工程里面,调用静态库,结果如下(代码粗略请大家无视...):

"ViewController.h"
@interface ViewController : UIViewController

@end

"ViewController.m"
#import "ViewController.h"
#import "Library.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  // 十六进制转二进制
  NSLog(@"十六进制转二进制: %@", [Library getBinaryByhex:@"F"]);
}

日志打印输入结果是:
静态库的使用[1006:40288] 十六进制转二进制: 1111

(四)制作静态库-Release版本:

跟Debug版步骤一样,只不过在编译时,改下面的选项即可如图12所示:

  

这时不管是真机还是模拟器都可以编译通过,正常运行;而使用者只能通过头文件知道我们提供的借口,却不知道实现文件中实现的细节,这有效地隐藏了自己的核心技术和机密内容;

以上就是我对iOS静态库的理解与解释,希望大家相互补充相互学习。

iOS创建与使用静态库的更多相关文章

  1. HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题

    HTML5在微信内置浏览器下,在右上角菜单的调整字体导致页面显示错乱的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  2. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. ios – containerURLForSecurityApplicationGroupIdentifier:在iPhone和Watch模拟器上给出不同的结果

    我使用默认的XCode模板创建了一个WatchKit应用程序.我向iOSTarget,WatchkitAppTarget和WatchkitAppExtensionTarget添加了应用程序组权利.(这是应用程序组名称:group.com.lombax.fiveminutes)然后,我尝试使用iOSApp和WatchKitExtension访问共享文件夹URL:延期:iOS应用:但是,测试NSURL

  4. ios – Testflight无法安装应用程序

    我有几个测试人员注册了testflight并连接了他们的设备……他们有不同的ios型号……但是所有这些都有同样的问题.当他们从“safari”或“testflight”应用程序本身单击应用程序的安装按钮时……达到约90%并出现错误消息…

  5. ibm-mobilefirst – 在iOS 7.1上获取“无法安装应用程序,因为证书无效”错误

    当我的客户端将他们的设备更新到iOS7.1,然后尝试从AppCenter更新我们的应用程序时,我收到了上述错误.经过一番搜索,我找到了一个类似问题的帖子here.但是后来因为我在客户端使用AppCenter更新应用程序的环境中,我无法使用USB插件并为他们安装应用程序.在发布支持之前,是否有通过AppCenter进行下载的解决方法?

  6. ios – 视图的简单拖放?

    我正在学习iOS,但我找不到如何向UIView添加拖放行为.我试过了:它说“UIView没有可见的接口声明选择器addTarget”此外,我尝试添加平移手势识别器,但不确定这是否是我需要的它被称为,但不知道如何获得事件的坐标.在iOS中注册移动事件回调/拖放操作的标准简单方法是什么?

  7. ios – 什么控制iTunes中iPhone应用程序支持的语言列表?

    什么控制iPhone应用程序的iTunes页面中支持的语言?

  8. ios – 获得APNs响应BadDeviceToken或Unregistered的可能原因是什么?

    我知道设备令牌在某些时候是有效的.用户如何使其设备令牌变坏?从关于“未注册”的文档:Thedevicetokenisinactiveforthespecifiedtopic.这是否意味着应用程序已被删除?.您应该看到四种分发方法:如果您选择AppStore或Enterprise,您将在后面的对话框中看到Xcode将APNS权利更改为生产:如果选择AdHoc或Development,则aps-environment下的文本将是开发,然后应与后端的配置匹配.

  9. ios – 当我关闭应用程序时,我从调试器获得消息:由于信号15而终止

    我怎么能解决这个问题,我不知道这个链接MypreviousproblemaboutCoredata对我的问题有影响吗?当我cmd应用程序的Q时,将出现此消息.Messagefromdebugger:Terminatedduetosignal15如果谁知道我以前的问题的解决方案,请告诉我.解决方法>来自调试器的消息:每当用户通过CMD-Q(退出)或STOP手动终止应用程序(无论是在iOS模拟器中还是

  10. ios – NSUbiquityIdentityDidChangeNotification和SIGKILL

    当应用程序被发送到后台时,我们会删除观察者吗?我遇到的问题是,当UbiquityToken发生变化时,应用程序终止,因为用户已经更改了iCloud设置.你们如何设法订阅这个通知,如果你不这样做,你会做什么来跟踪当前登录的iCloud用户?

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部