ACCESS静态库、动态库的不同汇总

real framework中不得以应用项目 或 不得以不含有类公事

real framework 中直接调用NSClassFromString函数会回来null
 需要强制加载指定类 或 直接通过类名引用

linux中静态库和动态库的区分

一、不同

库从本质上来说是一种可进行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库二种。 

  1. 静态函数库

   
那类库的名字一般是libxxx.a;利用静态函数库编译成的文书相比大,因为整个
函数库的兼具数据都会被重组进目的代码中,他的助益就鲜明了,即编译后的施行顺序不须求外部的函数库匡助,因为具有应用的函数都早就被编译进去了。当然那也会变成她的败笔,因为即便静态函数库改变了,那么您的主次必须再度编译。

  1. 动态函数库

    那类库的名字一般是libxxx.so;绝对于静态函数库,动态函数库在编译的时候
并不曾被编译进目标代码中,你的程序执行到有关函数时才调用该函数库里的呼应函数,因而动态函数库所暴发的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运作环境中必须提供相应的库。动态函数库的更改并不影响您的次序,所以动态函数库的升级换代相比便于。

二、相同

都是由*.o目的文件生成

ios 开发中 动态库 与静态库的分别

接纳静态库的益处

1,模块化,分工同盟

2,防止少量改动平常导致巨量的再次编译连接

3,也足以引用,注意不是共享利用

动态库使用有如下好处:

1使用动态库,可以将末了可执行文件体积收缩

2选用动态库,三个应用程序共享内存中得同一份库文件,节省资源

3行使动态库,可以不重复编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目标。

从1可以得出,将全部应用程序分模块,团队合营,举行分工,影响比较小。

等任何利益,

从2足以看看,其实动态库应该叫共享库,那么从那个含义上来说,苹果禁止iOS开发中运用动态库就可以明白了:

因为在前天的索尼爱立信,iPodTouch,华为平板上边程序都是单进度的,也就是某一时刻唯有一个经过在运转,那么您写个共享库,

       
—-共享给哪个人?(你使用的时候唯有你一个应用程序存在,其他的应当被挂起了,即使是可以而且多个进度运行,旁人能应用你的共享库里的东西啊?你那么些是给你协调的先后定制的。)

       
—-方今苹果的AppStore不支持模块更新,不能立异某个单独文件(除非自己写一个翻新机制:有投机的服务端放置最新动态库文件)

至于苹果为何禁止ios开发应用动态库我就猜到下边俩原因

长远理解金立静态库

      
在其实的编程进度中,常常会把有些公用函数制成函数库,供其他程序行使,一则提搞了代码的复用;二则提搞了要旨技术的保密程度。所以在实质上的门类支付中,平时会接纳到函数库,函数库分为静态库和动态库三种。和一大半人所熟稔的动态语言和静态语言同样,那里的所谓静态和动态是相持编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需求改静态库;而动态库在先后编译时并不会被链接到目的代码中,只是在程序运行时才被载入,因为在程序运行时期还亟需动态库的存在。

  Samsung官方只匡助静态库联编。

长远掌握framework(框架,其实一定于静态框架,不是动态库)

打包framework依然一个相比主要的功能,可以用来做一下事情:

(1)封装功能模块,比如有相比较成熟的功用模块封装成一个包,然后未来自己或其余同事用起来相比便宜。

(2)封装项目,有时候会遇见这几个境况,就是一家集团找了三个开发公司做五个品类,然后必要她们的档次中的一个嵌套进另一个类型,此时也可以把呗嵌套的连串打包成framework放进去,那样比较方便。

 

咱俩为啥须要框架(Framework)?

要想用一种开发者友好的措施共享库是很劳累的。你不单需求包含库本身,还要参加所有的头文件,资源等等。

苹果解决这些问题的点子是框架(framework)。基本上,那是富含一定结构并蕴藏了引用该库时所必不可少的享有东西的文件夹。不幸的是,iOS禁止所有的动态库。同时,苹果也从Xcode中移除了制造静态iOS框架的功力。

Xcode仍能协助创造框架的效应,重启那些效果,大家需求对Xcode做一些小小改变。

把代码封装在静态框架是被app
store所允许的。即便格局不相同,本质上它仍然是一种静态库。

框架(Framework)的类别

一大半框架都是动态链接库的款式。因为唯有苹果才能在iOS设备上设置动态库,所以我们无能为力创立这连串型的框架。

静态链接库和动态库一样,只可是它是在编译时链接二进制代码,因而利用静态库不会有动态库那样的题目(即除去苹果哪个人也无法在iOS上应用动态库)。

“伪”框架是透过破解Xcode的目的Bundle(使用一些脚本)来落到实处的。它在表面上以及选取时跟静态框架并无分歧。“伪”框架项目标成效大致和真正的框架项目尚未分别(不是总体)。

“嵌入”框架是静态框架的一个包裹,以便Xcode能拿到框架内的资源(图片、plist、nib等)。

此次发布包罗了创办静态框架和“伪”框架的模版,以及两岸的“嵌入”框架。

用哪类模板?

这次公布有五个模板,每个模板都有“强”“弱”三个项目。你可以挑选最符合一种(或者两种都设置上)。

最大的不比是Xcode不可能成立“真”框架,除非你安装静态框架文件xcspec在Xcode中。那真是一个遗憾(那么些文件是给项目选取的,而不是框架要用的)。

简单第

粗略说,你能够如此决定用哪类模板:

若果你不想修改Xcode,那么请使用“伪”框架版本

假如您只是想共享二进制(不是连串),三种都可以

假如您想把框架共享给不想修改Xcode的开发者,使用“伪”框架版本

要是您想把框架共享给修改过Xcode的开发者,使用“真”框架版本

一旦您想把框架项目作为另一个门类的信赖(通过workspace或者子项目标不二法门),请使用“真”框架(或者“伪”框架,使用-framework——见后)

设若你想在您的框架项目中投入其它静态库/框架,并把它们也链接到最终结果以便不须求单独添加到用户项目中,使用“伪”框架

“伪”框架

“伪”框架是破解的“reloacatable object file”(可重定位格式的目的文件,
保存着代码和多少,适合于和任何的靶子文件三番五次到联合,用来创设一个可举办对象文件或者是一个可共享目的文件),它可以让Xcode编译出类似框架的东西——其实也是一个bundle。

“伪框架”模板把方方面面进度分成多少个步骤,用一些脚本去暴发一个着实的静态框架(基于静态库而不是reloacatable
object
file)。而且,框架项目或者把它定义为wrapper.cfbundle类型,一种Xcode中的“二等公民”。

就此它跟“真”静态框架一样可以正常工作,但当存在依靠关系时就有劳动了。

凭借问题

假如不选择看重,只是成立普通的花色是不曾别的问题的。可是只要选拔了档次器重(比如在workspace中),Xcode就悲剧了。当你点击“Link
Binary With
Libraries”下方的’+’按钮时,“伪框架”无法出示在列表中。你可以从你的“伪”框架项目标Products上边将它手动拖入,但当你编辑你的主项目时,会并发警示:

warning: skipping file ‘/somewhere/MyFramework.framework’
(unexpectedfile type ‘wrapper.cfbundle’ in Frameworks & Libraries build
phase)

并陪同“伪”框架中的链接错误。

万幸的是,有个办法来缓解它。你可以在”Other Linker
Flags”中用”-framwork”开关手动告诉linker去使用你的框架举行链接:

-framework MyFramework

警戒依然存在,但最少能科学链接了。

添加其他的库/框架

只要你进入其余静态(不是动态)库/框架到您的“伪”框架项目中,它们将“链接”进你最终的二进制框架文件中。在“真”框架项目中,它们是纯引用,而不是链接。

您可以在品种中仅仅包涵头文件而不是静态库/框架本身的格局防止那种情景(以便编译通过)。

“真”框架

“真”框架各样方面都适合“真”的规范。它是实在的静态框架,正如应用苹果在从Xcode中去除的更加效能所创办的同一。

为了能制造真正的静态框架项目,你必需在Xcode中安装一个xcspec文件。

假设你公布一个“真”框架项目(而不是编译),希望去编译那些框架的人少不了也安装xcspec文件(使用这次发表的装置脚本),以便Xcode能驾驭目的项目。

注意:倘使您正在揭橥完全编译的框架,而不是框架项目,最后用户并不需求安装其余东西。

自己早已付出一个告知给苹果,希望他们在Xcode中创新这些文件,但那须要或多或少时间.OpenRadarlink
here

加其他静态库/框架

假定你投入此外静态(不是动态)库/框架到您的“真”框架项目,它们只会被引用,而不会象“伪”框架一样被链接到最后的二进制文件中。

从早期版本升级

若果你是从Mk6仍旧更早的本子升级,同时利用“真”静态框架,并且利用Xcode4.2.1从前的本子,请运行uninstall_legacy.sh以卸载早期用于Xcode的具备立异。然后再运行install.sh,重启Xcode。借使您利用Xcode4.3将来,只要求周转install.sh不分轩轾启Xcode。

安装

分级运行Real Framework目录或Fake
Framework目录下的install.sh脚本进行设置(或者五个你都运作)。

重启Xcode,你将在新品类携带的Framework&Library下看到StaticiOS
Framework(或者Fake Static iOS Framework)。

卸载请运行unistall.sh脚本一碗水端平启Xcode。

开创一个iOS框架项目

创办新类型。

连串项目选择Framework&Library下的Static iOS Framework(或者Fake Static
iOS Framework)。

分选“包涵单元测试”(可选的)。

在target中到场类、资源等。

凡是其余品种要运用的头文件,必需评释为public。进入target的Build
Phases页,展开Copy
Headers项,把需求public的头文件从Project或Private部分拖拽到Public部分。

编译你的 iOS 框架

慎选指定target的scheme

修改scheme的Run配置(可选)。Run配置默许使用Debug,但在准备布署的时候你可能想行使Release。

编译框架(无论目标为iOS
device和Simulator都会编译出同样的二进制,因而选何人都不在乎了)。

从Products下选中您的framework,“show in Finder”。

在build目录下有三个文本夹:(yourframework).framework and (your
framework).embeddedframework.

假诺你的框架唯有代码,没有资源(比如图片、脚本、xib、coredata的momd文件等),你可以把(yourframework).framework 分发给你的用户就行了。借使还包罗有资源,你必需分发(your
framework).embeddedframework
给您的用户。

干什么必要embedded
framework?因为Xcode不会寻找静态框架中的资源,倘若您分发(your
framework).framework, 则框架中的所有资源都不会来得,也不可用。

一个embedded
framework只是一个framework之外的增大的包,包含了那些框架的具有资源的号子链接。那样做的目标是让Xcode可以找到那个资源。

使用iOS 框架

iOS框架和正常的Mac OS动态框架大概,只是它是静态链接的而已。

在您的品类中拔取一个框架,只需把它拖仅你的类型中。在含有头文件时,记住使用尖括号而不是双引号括住框架名称。例如,对于框架MyFramework:

#import <MyFramework/MyClass.h>

运用问题

Headers Not Found

设若Xcode找不到框架的头文件,你恐怕是忘记将它们表明为public了。参考“创制一个iOS框架项目”第5步。

No Such Product Type

倘诺你没有安装iOS Universal
Framework在Xcode,并企图编译一个universal框架项目(对于“真”框架,不是“假”框架),那会促成下列错误:

target specifies product type
‘com.apple.product-type.framework.static’,but there’s no such product
type for the ‘iphonesimulator’ platform

为了编译“真”iOS静态框架,Xcode必要做一些改观,因而为了编译“真”静态框架项目,请在有着的开发条件中安装它(对于使用框架的用户不需求,只有要编译框架才须要)。

The selected run destination is not valid for this action

奇迹,Xcode出错并加载了错误的active设置。首先,请尝试重启Xcode。如若不当继续存在,Xcode暴发了一个坏的品种(因为Xcode4的一个bug,任何项目标花色都会产出那个问题)。若是是那样,你须求创立一个新类型重来一次。

链接警告

率先次编译框架target时,Xcdoe会在链接阶段报告找不到文件夹:

ld: warning: directory not found for
option’-L/Users/myself/Library/Developer/Xcode/DerivedData/MyFramework-ccahfoccjqiognaqraesrxdyqcne/Build/Products/Debug-iphoneos’

那儿,可以clean并再次编译target,警告会消除。

Core Data momd not found

对于框架项目和应用程序项目,Xcode会以区其他主意编译momd(托管对象模型文件)。Xcode会不难地在根目录创造.mom文件,而不会成立一个.momd索引(目录中涵盖VersionInfo.plist和.mom文件)。

那象征,当从一个embedded
framework的model中实例化NSManagedObjectModel时,你必需使用.mom伸张名作为model的URL,而不是采取.momd扩大名。

NSURL *modelURL = [[NSBundle mainBundle]URLForResource:@”MyModel”
withExtension:@”mom”];

Unknown class MyClass in Interface Builder file.

出于静态框架选用静态链接,linker会剔除所有它认为没用的代码。不幸的是,linker不会检查xib文件,由此一旦类是在xib中援引,而从未在O-C代码中引用,linker将从最后的可执行文件中删除类。那是linker的题材,不是框架的题材(当你编译一个静态库时也会发生那么些题目)。苹果内置框架不会暴发那个题材,因为他俩是运行时动态加载的,存在于iOS设备固件中的动态库是不能被删去的。

有四个缓解的艺术:

     让框架的最后用户关闭linker的优化增选,通过在他们的项目的Other
Linker Flags中添加-ObjC和-all_load。

   
 在框架的另一个类中加一个此类的代码引用。例如,如果你有个MyText菲尔德类,被linker剔除了。如若你还有一个MyViewController,它在xib中应用了MyText菲尔德(Field),MyViewController并没有被去除。你应当这么做:

在MyTextField中:

+ (void)forceLinkerLoad_ {}

在MyViewController中:

+(void) initialize {     [MyTextField forceLinkerLoad_]; }

他们依然需求加上-ObjC到linker设置,但不必要强制all_load了。

第2种方法须求你多做一些工作,但却让最后用户幸免在应用你的框架时关闭linker优化(关闭linker优化会导致object文件膨胀)。

unexpected file type ‘wrapper.cfbundle’ in Frameworks &Libraries build
phase

那么些题材暴发在把“假”框架项目作为workspace的借助,或者把它当作子项目时(“真”框架项目并未那几个题材)。即使那种框架项目暴发了不利的静态框架,但Xcode只可以从品类文件中看看那是一个bundle,由此它在自我批评信赖性时暴发一个告诫,并在linker阶段跳过它。

您可以手动添加一个指令让linker在链接阶段能科学链接。在凭借你的静态框架的类型的OtherLinker
Flags中加入:

-framework MyFramework

警戒仍旧存在, 但不会促成链接失利。

Libraries being linked or not being linked into the finalframework

很懊丧, “真”框架和“假”框架模板在拍卖引入的静态库/框架的做事办法各异的。

“真”框架模板选取常规的静态库生成步骤,不会链接其余静态库/框架到终极生产物中。

“假”框架模板选择“欺骗”Xcode的伎俩,让它认为是在编译一个可重平昔格式的对象文件,在链接阶段就不啻编译一个可执行文件,把具有的静态代码文件链接到最一生成物中(尽管不会检讨是或不是确实目的代码)。为了达成象“真”框架一样的成效,你可以只包罗库/框架的头文件到您的档次中,而不需要包括库/框架本身。

Unrecognized selector in (some class with a category method)

若果您的静态库或静态框架包涵了一个模块(只在品种代码中表明,没有类已毕),linker会搞不清楚,并把代码从二进制文件中剔除。因为在结尾生成的文件中从未那几个措施,所以当调用那几个类型中定义的办法时,会报一个“unrecognizedselector”卓殊。

要缓解这些,在含蓄那么些项目的模块代码中加一个“假的”类。linker发现存在完整的O-C类,会将项目代码链接到模块。

自我写了一个头文件 LoadableCategory.h,以减轻那一个工作量:

#import “SomeConcreteClass+MyAdditions.h”

#import
“LoadableCategory.h”  MAKE_CATEGORIES_LOADABLE(SomeConcreteClass_MyAdditions);  
@implementation SomeConcreteClass(MyAdditions)

  … 

@end

在应用这几个框架时,仍旧还索要在Build Setting的Other Linker
Flags中进入-ObjC。

执行别的代码前单元测试崩溃

设若您在Xcode4.3中创建静态框架(或库)target时,勾选了“withunit
tests”,当你打算运行单元测试时,它会崩溃:

Thread 1: EXC_BAD_ACCESS (code=2, address=0x0) 0 0x00000000 — 15
dyldbootstrap:start(…)

那是lldb中的一个bug。你可以用GDB来运作单元测试。编辑scheme,拔取Test,在Info标签司令员调试器Debugger从LLDB改为GDB。

摘自:http://blog.csdn.net/stackhero/article/details/9032999

相关文章