• 转载《Xcode 创建静态库和动态库》


    Xcode 创建静态库和动态库

    地址链接   http://www.cocoachina.com/ios/20150921/13385.html

    1、linux中静态库和动态库区别:

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

    静态库:这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

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

    2、iOS开发中静态库和动态库区别:

    静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。

    静态库 好处:

    i.模块化,分工合作,提高了代码的复用及核心技术的保密程度

    ii.避免少量改动经常导致大量的重复编译连接

    iii.也可以重用,注意不是共享使用

    动态库 好处:

    i.使用动态库,可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,进行分工,影响比较小

    ii.使用动态库,多个应用程序共享内存中得同一份库文件,节省资源

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

    iv.应用插件化

    v.软件版本实时模块升级

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

    3、Xcode创建静态库

    打开Xcode, 选择File ----> New ---> Project。 新建工程。 选择iOS ----> Framework & Library ---> Cocoa Touch Static Library。 点击Next。创建工程:


    blob.png

    新增2个类作为我们的一个静态类文件:


    blob.png

    其中LogLib.h的代码如下:(作为公开存在)

    blob.png

    LogLib.m实现方法如下,变成静态库后该文件隐藏:


    blob.png

    然后选择真机进行静态库的创建:(command + B)

    blob.png

    这个时候会出现如下的错误提示:


    blob.png

    按照错误的提示得知我们需要在iOS8.1下build需要选择证书:


    blob.png

    好了,在Product下会存在libStaticLib.a文件:

    blob.png

    这只是真机下的一个静态库,同样选择模拟器,command + B,生成模拟器下的静态库。

    找到这2个新建的静态库文件:


    blob.png

    分别用2个.a加入到其他项目在不同运行坏境选择不同的.a静态库明显不明智,打开终端,输入以下命令行进行整合:

    lipo -create 真机.a路径 模拟器.a路径 -output 整合的.a路径

    1
    lipo -create /Users/fangdd/Library/Developer/Xcode/DerivedData/StaticLib-ercfdooewtvlxmakqvyxkohcagph/Build/Products/Debug-iphoneos/libStaticLib.a /Users/fangdd/Library/Developer/Xcode/DerivedData/StaticLib-ercfdooewtvlxmakqvyxkohcagph/Build/Products/Debug-iphonesimulator/libStaticLib.a -output /Users/fangdd/Desktop/staticLib.a

    会在 整合的.a路径下找到合体的静态库。

    将生产的静态库及相应的头文件加入到我们的测试项目中,运行得到:

    blob.png

    完毕.

    4、Xcode创建动态库

    打开Xcode, 选择File ----> New ---> Project。 新建工程。 选择iOS ----> Framework & Library ---> Cocoa Touch Framework。 点击Next。创建工程:

    blob.png

    命名为DymicLib:


    blob.png

    同样的添加新的2个类作为测试:

    blob.png

    将头文件作为公共的头文件,提供给外部调用: 

    blob.png

    运行后变生成了一个动态库,找到Product下的DymicLib.framework所在的目录:

    blob.png

    注意这个只是运行坏境下的动态库(模拟器和真机),下面建立新的TARGETS:命名为CommonDymicLib:

    blob.png

    将之前生成的DymicLib加入到新的CommonDymicLib中:


    blob.png

    为CommonDymicLib添加新的脚本来实现模拟器和真机合并:

    blob.png

    blob.png

    脚本如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    # Sets the target folders and the final framework product.  
    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.  
    # 分别编译生成真机和模拟器使用的framework  
    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}/"  
       
    # Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.  
    # 使用lipo命令将其合并成一个通用framework  
    # 最后将生成的通用framework放置在工程根目录下新建的Products目录下  
    lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"  
       
    rm -r "${WRK_DIR}"

    选择iOS Device运行:

    blob.png

    找到生成的CommonDymicLib下的动态库DymicLib.framework:

    blob.png

    在测试项目中将DymicLib.framework加入:

    blob.png

    运行即可!

    心得:这个时候所谓的动态库其实意义就是升级版的静态库,因为动态库使用的前提是项目在发布前添加到项目中,这和我们所谓的插件(即插即用,随时在自己的服务器上下载一个动态库运行,而不需要重新打包,我们可以选择在需要的时候再加载动态库)完全是两码事。

    插件实现方式:使用dlopen加载动态库,动态库中真正的可执行代码为DymicLib.framework/DymicLib文件,因此使用dlopen时如果仅仅指定加载动态库的路径为DymicLib.framework是没法成功加载的。将我们创建的动态库放在我们的服务器,项目上线后再下载这个动态库到我们的Documents文件夹中,使用如下代码动态使用动态库:


    1
    2
    3
    4
    5
    6
    7
    8
    9
    #import NSString *documentsPath = [NSString stringWithFormat:@"%@/Documents/DymicLib.framework/DymicLib",NSHomeDirectory()];
    void * libHandle = NULL;
    libHandle = dlopen([documentsPath cStringUsingEncoding:NSUTF8StringEncoding], RTLD_NOW);
    if (libHandle == NULL) {
        char *error = dlerror();
        NSLog(@"dlopen error: %s", error);
    else {
        NSLog(@"dlopen load framework success.");
    }

    使用  动态库 中的类:

    1
    2
    3
    4
    5
    Class rootClass = NSClassFromString(@"DymicLog");
    if (rootClass) {
        id object = [[rootClass alloc] init];
        [(DymicLog *)object relog:@"hello world"];
    }
  • 相关阅读:
    poj 3310(并查集判环,图的连通性,树上最长直径路径标记)
    poj 3308(最小点权覆盖、最小割)
    poj 3281(网络流+拆点)
    poj 3275(传递闭包)
    poj 3204(最小割)
    poj 3164(最小树形图)
    poj 2987(最大权闭合图+割边最少)
    poj 2455(二分+最大流)
    poj 2391(二分+最大流)
    poj 2135(最小费用最大流)
  • 原文地址:https://www.cnblogs.com/-zone123/p/4826236.html
Copyright © 2020-2023  润新知