`

ios Static Dynamic Library Or Framework

阅读更多

 First, some general definitions (specific to iOS):

Static library

 

    - a unit of code linked at compile time, which does not change.

    However, iOS static libraries are not allowed to contain images/assets (only code). You can get around this challenge by using a media bundle though.

    A better, more formal definition can be found on Wikipedia here.

Dynamic library

 

    - a unit of code and/or assets linked at runtime that may change.

    However, only Apple is allowed to create dynamic libraries for iOS . You're not allowed to create these, as this will get your app rejected. (See this other SO post for confirmation and reasoning on such).

Software Framework

 

    - a compiled set of code that accomplishes a task... hence, you can actually have a static framework or a dynamic framework, which are typically just the compiled versions of the above.

    See the Wiki on Software Framework for more details.

    Hence on iOS, your only option is basically to use a static library or static framework (the main difference being that a static framework is distributed as a compiled.afile most often, whereas a static library may simply be included as a subproject - you can see all of the code - which is compiled first and its resulting.afile used a dependency by the project).

    Now that we're clear(er) on these terms, setting up a static library and supporting media bundle for iOS isn't too difficult, and there are many tutorials on how to do such. I personally would recommend this one:

    https://github.com/jverkoey/iOS-Framework

    This is a pretty straight-forward guide and doesn't have the disadvantage of dealing with "fake static libraries"... check it out for more info...

    Once you've created your static library, it's as easy as including it as a submodule within Git for use across different projects.

    Regarding a subproject within a project, as far as I know, in order to get this to work/compile correctly, you essentially have to setup a compile chain where the subproject is compiled first, which creates a static framework.afile that is used as a dependency by the project.

    Here's another useful tutorial which talks about this:

    http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/

 

<!--StartFragment -->
 

 

CocoaPods 终于支持了 Swift ,同时也发现Github团队的又一力作Carthage。它们都将包统一编译为Framework,但不同的是,Carthage 仅支持 iOS 8 & Xcode 6 Dynamic Framework 这一新特性。

那这个编译结果有什么区别?

Static Library & Dynamic Library

这两者属于标准的编译器知识,所以讲的会比较多。

简单的说,静态链接库是指模块被编译合并到应用中,应用程序本身比较大,但不再需要依赖第三方库。运行多个含有该库的应用时,就会有多个该库的Copy在内存中,冗余。

动态库可以分开发布,在运行时查找并载入到内存,如果有通用的库,可以共用,节省空间和内存。同时库也可以直接单独升级,或作为插件发布。

Library & Framework

在iOS中,Library 仅能包含编译后的代码,即 .a 文件。

但一般来说,一个完整的模块不仅有代码,还可能包含 .h 头文修的  .nib 视图文件  图片资源文件  说明文档 

Framework 作为 Cocoa/Cocoa Touch 中使用的一种资源打包方式,可以上述文件等集中打包在一起,方便开发者使用(就像Bundle)。

我们每天都要跟各种各样的Framework打交道。如 Foundation.framework / UIKit.framework 等,这些都是Cocoa Touch开发框架本身提供的,而且这些 Framework 都是动态库。

但Apple对待第三方开发者使用动态库的态度却是极端的否定,所以在iOS 7之前如果使用动态库是肯定会被reject的, reason 。但在2014年Xcode6和iOS 8发布时却开放了这个禁地,应该主要是为了 App Extension 

Framework 包含什么?

到底Framework中有什么,这里来看Alamofire编译后的结果:

 
Alamofire.framework
├── Alamofire
├── Headers
 ├── Alamofire-Swift.h
 └── Alamofire.h
├── Info.plist
├── Modules
 ├── Alamofire.swiftmodule
  ├── arm.swiftdoc
  ├── arm.swiftmodule
  ├── arm64.swiftdoc
  ├── arm64.swiftmodule
  ├── i386.swiftdoc
  ├── i386.swiftmodule
  ├── x86_64.swiftdoc
  └── x86_64.swiftmodule
 └── module.modulemap
└── _CodeSignature
    └── CodeResources

Framework 包括了二进制文件(可动态链接并且为每种处理器架构专属生成),这点和静态库并无区别,但不同的是,它包含其它资源:

  • 头文件 - 也包含Swift symbols所生成的头文件,如 Alamofire-Swift.h 
  • 所有资源文件的签名 - Framework被嵌入应用前都会被重新签名。
  • 资源文件 - 像图片等文件。
  • Dynamic Frameworks and Libraries - 参见 Umbrella Frameworks
  • Clang Module Map 和 Swift modules - 对应处理器架构所编译出的Module文件
  • Info.plist - 该文件中说明了作者,版本等信息。

Cocoa Touch Framework (实际内容为 Header + 动态链接库 + 资源文件)

Static Framework & Dynamic Framework

刚才也说明了Apple所创建的标准 Cocoa Touch Framework 里面包含的是 动态链接库 。而 Dynamic Framework 为 Xcode 6中引入的新特性,仅支持 iOS 8,因为Carthage使用的是该特性,所以仅支持iOS 8,说明上有提。

但新版CocoaPods中使用Framework是能够支持iOS 7的,这说明它不是Dynamic Framework。推断它仅是将Static Library封装入了Framework。还是静态库, 伪Framework 

关于Static Framework,见:

伪Framework 是指使用Xcode的Bundle来实现的。在使用时和Cocoa Touch Framework没有区别。但通过Framework,可以或者其中包含的资源文件(Image, Plist, Nib)。

Swift 与 Framework 的关系

在Xcode 6.0 Beta 4的 Release Notes 中,可以找到这句话:

 
Xcode does not support building static libraries that include Swift code. (17181019)

如果库是使用Swift语言开发,在build时会得到

 
unknown option character `X' in: -Xlinker

CocoaPods 将第三方都编译为Static Library。这导致Pod不支持Swift语言。所以新版Pod已将Static Library改为Framework。

Pods 0.36.0.beta.1 虽然已经支持Swift,但在编译时仍会给出下面警告:

 
ld: warning: embedded dylibs/frameworks only run on iOS 8 or later

其它扩展阅读:

Dynamic Framework

使用Dynamic 的优势:

  • 模块化,相对于Static Library,Framework可以将模块中的函数代码外的资源文件打包在一起。
  • 共享可执行文件 iOS 有沙箱机制,不能跨App间共享共态库,但Apple开放了 App Extension ,可以在App和Extension间共间动态库(这也许是Apple开放动态链接库的唯一原因了)。

iOS 8 Support only:

如果使用了动态链接库,在尝试编译到iOS 7设备上时,会出现在下错误:

 
ld: warning: directory not found for option '-F/Volumes/Mactop BD/repos/SwiftWeather/Carthage.build/iOS'
ld: embedded dylibs/frameworks are only supported on iOS 8.0 and later (@rpath/Alamofire.framework/Alamofire) for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

REF::

  • 大小: 100.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics