`
啸笑天
  • 浏览: 3435055 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

iOS的framework动态库

 
阅读更多

 

 

iOS的静态库有两种,.a和.framework, 动态库.framework居多(还有. dylib). 静态库建议也生成.framework模式的,好处是.framework包含了相关的.h文件等..a文件还要自己添加相关的.h文

 

动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存.系统提供的库基本上都属于此类,例如UIKit等,A应用和B应用中都用到了UIKit,系统只加载了一份在内存中.IOS中对于第三方的动态库,很遗憾,目前还不支持的.

 

iOS上动态库可以做什么?

和静态库在编译时和app代码链接并打进同一个二进制包中不同,动态库可以在运行时手动加载,这样就可以做很多事情,比如:

共享可执行文件:在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,iOS仍然不允许进程间共享动态库,即iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。 不过iOS8上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。

注意:sandbox会验证动态库的签名,所以如果是动态从服务器更新的动态库,是签名不了的,因此应用插件化、软件版本实时模块升级等功能在iOS上无法实现。

 

项目framework管理工具:

CocoaPods 0.36开始支持动态库,Carthage也只支持动态库 ,所以都仅支持>=iOS8版本。

 

framework配置注意点:

***编译成功,但发现很多关于符号表的警告,这时需要将Generate Debug Symbols设置为NO即可关闭符号表警告。

***支持bitcode,在TAGETS的Build setting中搜索Other C Flags,添加命令“-fembed-bitcode”。

***在TARGETS->Build Phases->Headers里面,有三种类别。Public(公共的),这里存放供其他人查看的header。Private(私有的)这里存放私有的Header,以上两个Headers存放位置都会暴露出来,所有人可以查看。有些Header是不想给别人看到的。这种header放在第三个类Project中。

 

 

生成framework脚本:

 

set -e

# Sets the target folders and the final framework product.
FMK_TARGET_NAME=${PROJECT_NAME}
FMK_NAME=${PROJECT_NAME}

WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
UNIVERSAL_OUTPUTFOLDER=${SRCROOT}/Products

# Cleaning the oldest.
if [ -d "${UNIVERSAL_OUTPUTFOLDER}" ]
then
rm -rf "${UNIVERSAL_OUTPUTFOLDER}"
fi

mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Build Device and Simulator versions
xcodebuild -target "${FMK_TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration "Release" -sdk iphoneos  clean build
xcodebuild -target "${FMK_TARGET_NAME}" -configuration "Release" -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO  clean build

#  Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${DEVICE_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/"

# 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 "${UNIVERSAL_OUTPUTFOLDER}/${FMK_NAME}.framework/${FMK_NAME}"

#  Convenience step to open the project's directory in Finder
rm -r "${WRK_DIR}"

open "${UNIVERSAL_OUTPUTFOLDER}"
 

 使用动态库:

需要把动态库加入:Embedded Binaries 和 Linked Frameworks and Libraries。

加入Embedded Binaries,是因为Targets-->Build Setting-->Linking-->Runpath Search Paths中默认设置是@executable_path/Frameworks ,@executable_path/表示可执行文件所在路径,即沙盒中的.app目录,Embedded Binaries就是这个Frameworks目录下。如果你将动态库放到了沙盒中的其他目录,只需要添加对应路径的依赖就可以了。

Targets-->Build Phases-->Link Frameworks With Libraries 就是对动态库的链接。动态库的另一个重要特性就是即插即用性,我们可以选择在需要的时候再加载动态库,framework对应的Status由默认的Required改成Optional;或者更干脆的,将framework从Link Binary With Libraries列表中删除改为手动加载。

 

手动加载及调用:

-(void)testFramework
{
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *documentDirectory = nil;
    if ([paths count] != 0)
        documentDirectory = [paths objectAtIndex:0];
    
    //拼接我们放到document中的framework路径
    NSString *libName = @"DframeworkDocuments.framework";
    NSString *destLibPath = [documentDirectory stringByAppendingPathComponent:libName];
    
    //判断一下有没有这个文件的存在 如果没有直接跳出
    NSFileManager *manager = [NSFileManager defaultManager];
    if (![manager fileExistsAtPath:destLibPath]) {
        NSLog(@"There isn't have the file");
        return;
    }
    
    //复制到程序中
    NSError *error = nil;
    
    //加载方式一:使用dlopen加载动态库的形式 使用此种方法的时候注意头文件的引入
    //    void* lib_handle = dlopen([destLibPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_LOCAL);
    //    if (!lib_handle) {
    //        NSLog(@"Unable to open library: %s\n", dlerror());
    //        return;
    //    }
    //加载方式一 关闭的方法
    // Close the library.
    //    if (dlclose(lib_handle) != 0) {
    //        NSLog(@"Unable to close library: %s\n",dlerror());
    //    }
    
    //加载方式二:使用NSBundle加载动态库
    NSError *err = nil;

    NSBundle *frameworkBundle = [NSBundle bundleWithPath:destLibPath];
    if (frameworkBundle && [frameworkBundle loadAndReturnError:&err]) {
        NSLog(@"bundle load framework success.");
    }else {
        NSLog(@"bundle load framework err:%@",error);
        return;
    }
    
    /*
     *通过NSClassFromString方式读取类
     *PacteraFramework 为动态库中入口类
     */
    Class pacteraClass = NSClassFromString(@"PacteraFramework");
    if (!pacteraClass) {
        NSLog(@"Unable to get TestDylib class");
        return;
    }
    
    /*
     *初始化方式采用下面的形式
      alloc init的形式是行不通的
      同样,直接使用PacteraFramework类初始化也是不正确的
     *通过- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
      方法调用入口方法(showView:withBundle:),并传递参数(withObject:self withObject:frameworkBundle)
     */
    NSObject *pacteraObject = [pacteraClass new];
    [pacteraObject performSelector:@selector(showView:withBundle:) withObject:self withObject:frameworkBundle];
    
}

 

 

 

 thx:

http://foggry.com/blog/2014/06/12/wwdc2014zhi-iosshi-yong-dong-tai-ku/

http://blog.lanvige.com/2015/01/04/library-vs-framework-in-ios/?utm_source=tuicool&utm_medium=referral

http://justsee.iteye.com/blog/2212570

分享到:
评论
2 楼 啸笑天 2016-04-22  
iOS 静态库,动态库与 Framework
  https://segmentfault.com/a/1190000004920754?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
1 楼 啸笑天 2016-04-22  
http://www.tuicool.com/articles/a6BRnqF     Build Swift Framework

相关推荐

    IOS 静态库和Framework区别

    主要介绍了IOS 静态库和Framework区别的相关资料,这里对动态库与静态库做比较,选择什么时候使用库文件,需要的朋友可以参考下

    ios 代码注入(Framework)

    ios 动态库 代码注入(Framework)

    IOS 热更新,实时代码更新,动态更新,动态库framework

    IOS 热更新,实时代码更新,动态更新,动态库framework http://blog.csdn.net/jianrenbubai/article/details/50351507

    IOS创建静态Framework模板

    因为动态framework的生成需要IOS8.0以上的系统才能支持,否则不能上架,所以在支持IOS7.0或者以下的代码的时候需要使用静态framework 1.确保XCode已完全关闭 2.解压缩zip文件并转到文件夹:Real Framework/install....

    iOS制作framework静态库图文教程

    最近在做ios的静态库(据说framework动态库不能上传到app store).a 和framework都做过了,这里就先说framework的制作流程: 1.首先在xcode下新建cocoa touch framework工程: 2.新建好工程后,往里面添加要封装的...

    iOS中封装.framework及使用的方法详解

    .framework是什么? 这个问题相信做iOS的都知道答案。 在我们的日常开发中,经常会用到各种已经封装好的库,比如支付宝、微信SDK等等中的库,这些库可以给我们的开发带来很大的便利。...“动态库”

    RobotFramework常用库简介.pdf

    ⽀持创建和验证⽇期和时间值以及它们之间的计算 扩展库 Robot Framework需要下载安装后才能使⽤的库,包括: Android library:所有android⾃动化需要的测试库,内部使⽤的是Calabash Android iOS library:...

    iOS中.a和.framework静态库的创建与.bundle资源包的使用详解

    前言 ...库实际上是一种代码共享的方式,主要用于代码重用和源码隐藏,通常分为动态库和静态库。 2. 区别 静态库:链接时完整的拷贝至可执行文件中,被多次使用就有多份冗余拷贝。 动态库:链接时不

    HTML移动端框架Framework7.zip

    Clone 或者下载 Framework7 库2. 修改 Kitchen Sink 绑定到应用中,或者从 dist/ 下的文件夹绑定主要特性:1.非常容易使用,不比网站的制作难! 2. 专注于 iOS 7,支持 iOS 7 的原生外观和感觉3. 丰富的 UI 组件4. ...

    Framework7全功能 HTML 框架 v4.1.0

    Framework7 是一个开源的全功能 HTML 框架,用于构建具有 iOS 和 Android 原生外观的混合移动应用程序或 Web 应用程序。Framework7 也是独立的原型应用工具。Framework7 并非与所有平台兼容。它更多地专注于 iOS 和 ...

    iOS创建与使用静态库

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

    IOS 静态库打包流程简化详细介绍

    关于静态库和动态库区别,可以看我的另外一篇文章: iOS静态库和Framework区别 项目配置 新建一个名为TestSDK的静态库工程 然后点击Target下边的加号按钮,添加新的Target 选择Cross-platform,新建一个Aggregate...

    组件化-动态库实战1

    介绍先静态库和动态库都是以进制提供代码复的代码库静态库 常见的是 .aframework(in Apple): Framework 是Cocoa/Cocoa T

    iOS调试工具AllYourMemoriesAreBelong2iOS.zip

    如果你的 app 链接了 KVOController.framework,那么 AllYourMemoriesAreBelong2iOS 内部机制会自动利用其提供的现代化接口,否则则使用 Objective-C 标准库提供的原生 KVO 接口 如何使用 使用 ...

    制作动态及静态Framework

    有没有写SDK或者要将一些常用的工具类做成Framework的经历?你或许自己写脚本完成了这项工作,相信也有很多的人使用 iOS-Universal...关于静态库和动态库的概念,网上资料很多,这里不做叙述,只讲解制作过程。新建工程

    Framework7 (HTML 移动端框架) v4.1.0

    Framework7 (HTML 移动端框架)简介Framework7 或者叫 F7 是全功能的绑定 iOS 7 应用的 HTML 框架。Framework7 是免费开源的 HTML 移动端框架,用来开发混合移动端应用或者 iOS 7 的 Web 应用,并且带有 iOS 7 的原生...

    gdnative_ios:用于为iOS平台构建GDNative模块的入门项目

    SCons配置将构建静态( .a )或动态( .dylib )iOS库。 所有产生的产品均可用于在Godot项目中创建GDNative库。最初设定编译GDNative 要生成libgdnative.fat.a,请在godot -cpp目录中执行: scons platform=ios ios...

Global site tag (gtag.js) - Google Analytics