`
啸笑天
  • 浏览: 3465503 次
  • 性别: 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热更新 iOS热更新通常指的是通过网络下载并执行新的代码段,以替换原有的应用程序中的部分逻辑。这主要依赖于iOS系统...

    ios使用cmake编译framework

    这段代码中,`add_library`命令创建了一个动态库,`set_target_properties`设置了框架属性,`install`命令指定了安装(构建输出)路径,最后的`add_custom_command`用于生成框架结构,包括复制库文件到framework目录...

    IOS应用源码Demo-iOS framework 制作教程【非静态包】-毕设学习.zip

    一个Framework是iOS应用开发中的核心组件,它封装了可重用的代码库,提供了各种服务和功能。非静态Framework与静态Framework的主要区别在于,前者在运行时动态链接,而后者在编译时静态链接到应用程序中。动态框架...

    IOS 静态库和Framework区别

    - .framework文件:虽然名称相同,但这里的.framework是动态库形式,通常用于系统级别的服务。 五、关于.framework既是静态库又是动态库的问题 .framework既可以表示静态库也可以表示动态库,这取决于库的创建方式...

    IOS应用源码之【应用】iOS framework 制作教程【非静态包】.rar

    iOS Framework主要有两种类型:静态库(Static Library)和动态库(Dynamic Library)。静态库在编译时会合并到目标应用中,而动态库则在运行时由系统加载。本教程关注的是动态库,也称为动态框架(Dynamic ...

    ios创建framework静态库demo

    在iOS中,有静态库(Static Library)和动态库(Dynamic Library)两种形式。静态库在编译时会被链接到目标应用程序中,而动态库则在运行时加载。 **创建静态库步骤:** 1. **初始化项目**:打开Xcode,选择"File...

    iOS Framework制作打包教程

    打包的过程涉及到将你的项目编译成一个静态库(.a文件)或者动态库(.dylib文件),并将其与资源和头文件一起打包成Framework格式。 打包完成后,你会得到一个包含二进制文件、资源文件和头文件的包,这个包可以在...

    iOS Server 加载动态库 Demo (含Makefile)

    在iOS开发中,通常我们使用的库分为静态库(.a或.framework)和动态库(.dylib或.dylib)。静态库在编译时会被链接到可执行文件中,而动态库则是在运行时加载。由于安全性和App Store的规定,iOS应用程序(尤其是...

    ios 代码注入(Framework)

    在iOS中,框架(Framework)是动态库的一种特殊形式,包含了一组相关功能的集合,如库、头文件、资源文件等。使用框架可以使代码更易于管理和分发,同时减少应用程序的大小,因为共享的代码只需存储一次。 **代码...

    动态库IOS例子

    在iOS中,动态库主要分为两种类型: dylib(动态共享库)和 framework(框架)。dylib 是纯动态链接库,通常由系统或第三方服务提供,而framework则包含头文件、资源文件和dylib,更适合开发者的日常使用。 创建...

    iOS framework 制作教程,这次不是静态包!!!

    通常,我们接触到的iOS框架有两种类型:静态库(Static Library)和动态库(Dynamic Library)。本教程将重点讨论如何制作动态框架,因为标题明确指出“这次不是静态包”。动态框架在iOS 8及以上版本中被引入,它...

    Xcode创建和使用iOS的dylib动态库

    总结,Xcode创建和使用iOS的dylib动态库涉及到库的原理、创建过程、使用方法、版本管理、依赖处理以及模板和资源文件的处理等多个方面。熟练掌握这些知识点,可以提升iOS开发的效率和代码质量。通过不断实践和学习,...

    iOS制作FrameworkDemo

    `iOS Framework`是iOS SDK的一个重要组成部分,它是一个包含了可执行代码和资源文件的容器,可以理解为一种特殊的静态库或动态库。开发者可以创建自定义的Framework来封装特定的功能,然后在多个项目中重复使用。 ...

    IOS应用源码之【应用】-iOS framework 制作教程【非静态包】.rar

    本教程将重点讲解如何制作一个非静态的iOS框架,这涉及到动态库的创建,相比于静态库,动态库可以减少应用程序的大小,因为它们在运行时才被加载。以下是关于iOS框架制作的详细步骤和相关知识点: 1. **了解框架...

    动态库demo

    在iOS开发中,动态库(Dynamic Library)是一种重要的软件组件形式,它允许程序在运行时加载和使用代码,而不是在编译时将其嵌入到主应用程序中。动态库的使用可以减少应用程序的大小,因为多个应用可以共享同一库,...

    iOS制作framework静态库图文教程

    而动态库(Dynamic Library,如Framework)在运行时才被加载,可以减少应用程序的大小,但动态库不能直接上传到App Store。 以下是制作iOS静态库Framework的步骤: 1. **创建Cocoa Touch Framework工程**: 打开...

    iOS开发-动态库加载(实时模块更新).doc

    动态库的创建通常涉及创建一个新的Cocoa Touch Framework工程。例如,可以创建一个名为`DynamicLink`的框架,并在其中定义对外公开的方法,如`- (void)startWithObject:(id)object withBundle:(NSBundle *)bundle;`...

Global site tag (gtag.js) - Google Analytics