iOS中的静态库和动态库

iOS中的静态库和动态库

概念

静态库(Static Library)
以 .a 为后缀,它是你的源码的实现.m文件编译而成的二进制文件集合,需要配合上暴漏的.h文件使用,它在引用链接时拷贝至可执行文件中,程序运行时加载到内存,期间被多次使用就有多份冗余拷贝和加载;
动态库(Dynamic Framework)
.dylib.framework为后缀,也是一堆.h和.m的集合,.m同样被编译成了二进制,不同的是,它还可以包含nib文件,资源文件等,系统的framework在链接时先检查内存中是否已经加载,如果有,就不再进行复制,这样多个应用程序可以共享内存中得同一份库文件,节省了内存.

 

注意:
1.在iOS8之前,或者xcode6之前,你可能也见过开发者自己打包的framework,具体方法可以看这里这里,但是,这些辛苦打包出来的framework依然是静态库的形式(程序运行时被加载到内存,即便此时内存中其他应用也用了此framework并且已经加载进内存了);
2.系统的.framework是动态库,也就是说我们代码中最常见的#import <Foundation/Foundation.h>导入的foundation框架,当我们运行程序的时候,其实内存中已经预加载了这些系统框架,此时我们打开应用时不会再次加载这些,这就减少了内存的占用.虽然在xcode6之后苹果爸爸允许我们自己生成framework了,但是,它依然只是存在于当前应用的沙盒中而非提交到系统中,这就意味着每次依然会加载到内存中...

创建自己的framework

相比较于静态库,动态库有着自己的优势,除去上文中说道的资源包含和内存加载问题,在使用的时候相比较于.a的静态库也更方便,因为它本省包含了我们所需要的所有资源(自包含);所以我建议,我们更应该生成动态framework而非.a静态库;

为已有类扩展分类使我们经常的做法,现在我们将实例如何将分类打包成framework使用;
1.新建工程->选择iOS下Framework&Library->CocoaTouch Framework;

2.将我们的要打包的文件拖进工程,这里不要建立文件夹(图1);

可以看到这里有一个额外的文件XCommonExtension.h,它在我们生成工程之后自动为我们生成,这里你可以将打包的public文件都通过import的方式导入头文件到这里,在其他开发者使用framework的时候只用引用这个.h头文件即可;

3.在build phases中,我们可以看到有一个Headers的选项,我们上一步添加的文件都会在这里显示,不过默认的是在project下,这里我们需要把需要暴露的拖动到public下,完成后如下(图2)

4.Build-Run,到此,你的""模拟器版""的framework已经生成了,它只能在模拟器中链接引用,到真机运行的时候就有问题了,接下来,我们在生成真机版的framework,同时把他们合并成一个通用的framework;

5.选中target->在工具栏点击Editor->Add Target->在弹出的选择框中选择Other->Aggregate->Next;现在你的工程总有了两个target(图3)

 

6.选中刚加入的这个target,点击右上的 + 号 -> New Run Script Phase,我们将在这里嵌入我们的脚本script;

 

 

嵌入以下脚本:

复制代码
# Sets the target folders and the final framework product.
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
# 例如: FMK_NAME = "MyFramework"
FMK_NAME=${PROJECT_NAME}
# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
# Working dir will be deleted after the framework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build
# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
cp -R "${SIMULATOR_DIR}/" "${INSTALL_DIR}/"
# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"
rm -r "${WRK_DIR}"
open "${INSTALL_DIR}"
复制代码

7.选中新加入的这个Scheme,编译运行(图4);

 

 

8.编译运行之后你的finder就会弹出生成的framework,找到并拷贝出来,大功告成,下面我们就可以使用它了;

 
使用我们的framework

9.在新建的工程中加入我们生成的framework,在Embedded Framework中加入我们的framework,在要使用的文件中引入头文件;

 

 

import <XCommonExtension/XCommonExtension.h>

注意:
1.这里我们打包的为分类,在使用的时候,需要在other linker flag中添加-ObjC或者-force_load参数;
2.带有图片资源的需要把图片打包成Bundle文件,和framework一起拷贝到相应的项目中.



文章原址:http://www.cnblogs.com/pengsi/p/5555067.html

流程亲测有效


疑问:1:protect 文件 在public文件的.m中被引用,编译打包没有问题,framework引入到工程中会编译显示找不到文件。
   2:目录中添加文件夹:文件夹下的目录不会默认到public或者private或者protect中,编译打包没有问题,framework引入到工程中会编译显示找不到文件。
   3:如何应用其他的三方库,如不能打包,怎么引用呢?




二、打包bundle文件

1、新建OS X->Framework & Library->Bundle新建

2、在Build Settings->(null)-Deployment->iOS Deployment Target->选择自己需要支持的最低系统。

3、build后会生成一个bundle包,但在包中的图片由以前的png格式全部变成tiff格式。为了防止这种格式转变。需要在Build Settings->Architectures->Base SDK->选择iOS的SDK要支持的版本。这时TARGETS中Build Setting->User-Defined中会出现一个新的Key:COMBINE_HIDPI_DEBUG_INFO,把它设置为NO。

4、这样创建的图片资源不能使用[UIImage imageNamed:@“png”]来获取了。需要使用路径方式来读取图片。

这里我使用了一个函数来获取路径。

NSString *getKaYiKaImageBundlePath(NSString *filename);

NSString *getKaYiKaImageBundlePath(NSString *filename) {

NSBundle *libBundle = [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"KaYiKa.bundle"]];

if (libBundle && filename) {

NSString *path = [[libBundle resourcePath] stringByAppendingPathComponent:filename];

path = [path stringByAppendingString:@".png"];

return path;

}

return nil;

}

使用时直接用

[UIImage imageWithContentsOfFile:getKaYiKaImageBundlePath(@"tool_return_day")]获取图片。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值