iOS 库研究

作者: 我是小胡胡分胡 | 来源:发表于2017-07-25 09:31 被阅读72次

    一、linux库的创建和使用

    编译过程

    预处理.i , 编译.o , 汇编.s/.S , 链接.out(可执行程序)
    动态库 .so
    静态库 .a

    预处理: 头文件的包含, 宏定义的展开,编译条件的选择
    编译:经过词法分析,语法分析,把源代码翻译成中间语言,及汇编语言
    汇编:把汇编代码翻译成机器代码
    链接:是一个符号和地址的绑定的过程。把符号信息转换成可执行文件中的虚拟地址等。
    动态链接:通过动态符号找到内存地址。
    静态链接:链接后,重定位到绝对的虚拟内存地址,以便在运行时读取到该地之中的信息。

    静态库

    1、创建静态库

    gcc -c hello.c
    ar -r libhello.a hello.o

    2、使用静态库

    gcc test.c -lhello -L.
    gcc test.c libhello.a -L.

    编译参数说明
    -Ipath -Lpath -lname

    -Ipath
    指定的头文件查找,然后到默认的系统头文件查找:
    /usr/local/include
    /usr/include

    -lname
    指定库的名字,libname.so(去掉lib,去掉.so)

    -Lpath
    库搜索路径

    3、运行程序
    不需要指定库的搜索路径。

    动态库

    1、创建动态库
    gcc -shared hello.c -o libhello.so

    2、使用动态库
    gcc test.c -lhello -L.

    3、运行程序
    dyld: Library not loaded: libhello.so
    Reason: image not found

    需要指定库的搜索路径
    LD_LIBRARY_PATH
    export LD_LIBRARY_PATH=xxxxpath:$LD_LIBRARY_PATH

    /etc/ld.so.conf指定的动态库搜索路径
    默认的动态库搜索路径:
    /lib
    /usr/lib

    查询二进制文件所依赖的库列表
    gun linux上命令是ldd,freebsd drawin上是otool -L

    二、iOS 库的创建和使用

    https://my.oschina.net/kaqijiang/blog/649632
    http://blog.ibireme.com/2013/09/18/create-ios-static-framework/
    http://www.jianshu.com/p/56d5880b2e40
    https://segmentfault.com/a/1190000004920754
    http://www.jianshu.com/p/ad02ee195ca7

    1注意理解:无论是.a静态库还.framework静态库,我们需要的都是二进制文件+.h+其它资源文件的形式,不同的是,.a本身就是二进制文件,需要我们自己配上.h和其它文件才能使用,而.framework本身已经包含了.h和其它文件,可以直接使用。

    2图片资源的处理:两种静态库,一般都是把图片文件单独的放在一个.bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一个文件夹,把它改名为.bundle就可以了,右键,显示包内容可以向其中添加图片资源。

    3category是我们实际开发项目中经常用到的,把category打成静态库是没有问题的,但是在用这个静态库的工程中,调用category中的方法时会有找不到该方法的运行时错误(selector not recognized),解决办法是:在使用静态库的工程中配置other linker flags的值为-ObjC。

    4如果一个静态库很复杂,需要暴露的.h比较多的话,就可以在静态库的内部创建一个.h文件(一般这个.h文件的名字和静态库的名字相同),然后把所有需要暴露出来的.h文件都集中放在这个.h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出来就可以了。

    1、 创建、 编译

    cocoa touch framework
    Dynamic library(mach-o type默认此项):因为iOS沙盒限制不能在不同APP间访问动态库。使用者使用嵌入式动态库,需要添加到embedded binaries中。
    Static library:静态库

    cocoa touch static library
    iOS .a静态库

    validate architectures
    真机架构.a
    armv7: 3gs,4,4s
    armv7s: 5,5c
    arm64: 5s和以上

    模拟器架构.a
    i386:4,4s,5,5c
    x86_64:5s和以上

    build active architecture only为yes,真机build2种(armv7,arm64),模拟器build对应的1种架构

    debug:调试版本, 系统本身也会有一些调试代码. 此版本体积会稍大, 运行会稍慢
    release:发布版本, 系统会去除调试代码, 体积变小, 运行速度变快. 对用户来说没有明显的感觉

    合并库
    lipo create xx1.a xx2.a xx.a

    拆分库
    lipo Hyphenate.framework/Hyphenate -thin armv7 -output Hyphenate_armv7
    lipo Hyphenate.framework/Hyphenate -thin arm64 -output Hyphenate_arm64

    lipo -create Hyphenate_armv7 Hyphenate_arm64 -output Hyphenate

    替换framework
    mv Hyphenate Hyphenate.framework/

    2、使用库注意事项

    1)Other Linker Flags添加-ObjC:静态库里有Category方法,但是调用时报错“unrecognized selector send to instance.”
    2)Other Linker Flags添加-all_load或者-force_load xxx,如果你写了一个.m文件,并且里面只有一个Category,强制加载你的库的资源,或者在.m文件增加一下代码:
    YYSYNTH_DUMMY_CLASS(NSData_YYAdd)

    #ifndef YYSYNTH_DUMMY_CLASS
    #define YYSYNTH_DUMMY_CLASS(_name_) \
    @interface YYSYNTH_DUMMY_CLASS_ ## _name_ : NSObject @end \
    @implementation YYSYNTH_DUMMY_CLASS_ ## _name_ @end
    #endif
    
    

    3)静态库的开发者一定要把静态库中的东西全部加上Prefix来做保护:添加了静态库后,编译报错"有重复定义的符号(duplicate symbol )

    3、 使用使用cocoapods插件制作静态库

    能解决duplicate symbol问题

    mangle symbols of depedendant
    用class-dump可以验证。头文件和class类名都被加了前缀。

    pod package xx.podspec
    https://github.com/CocoaPods/cocoapods-packager

    三、cocoapods更新

    1,更新gem

    homebrew(brew)-》ruby-》gem
    http://www.jianshu.com/p/78c3166be2f3

    2,更新cocoapods

    1、升级cocoapods

    sudo gem install cocoapods --pre
    

    2、降级cocoapods
    执行sudo gem uninstall cocoapods 卸载现有 cocopods

    sudo gem install cocoapods -v 0.39.0
    

    3、更新本地cocoapods库
    pod repo update --verbose

    4、验证
    再查看本地安装过的cocopods相关东西,命令如下:
    gem list --local | grep cocoapods会显示如下

    gem list --local|grep cocoapods
    cocoapods (1.2.0.beta.3, 1.1.1)
    cocoapods-core (1.2.0.beta.3, 1.1.1)
    cocoapods-deintegrate (1.0.1)
    cocoapods-downloader (1.1.3, 1.1.2)
    cocoapods-plugins (1.0.0)
    cocoapods-search (1.0.0)
    cocoapods-stats (1.0.0)
    cocoapods-trunk (1.1.2, 1.1.1)
    cocoapods-try (1.1.0)
    

    四、创建自己的pod库

    1、创建git源代码仓库

    2、创建podspec文件pod spec create NAME

    3、编辑podspec文件source,resources,source_files等,哪些源代码仓库中的内容需要pods管理,就在podspec中设置对应的规则。保证源代码仓库能被成功编译。

    4、检测podspec规范是否合法有效pod spec lint xxx.podspec

    5、创建私有的specs仓库
    也可以把源代码库仓库同时作为specs仓库, 提交podspec文件到源码git中,不需要 6,7两步。pod 'MyKit', :git => 'https://git.coding.net/xxx/Mykit.git'

    6、把specs仓库克隆到本地pod repo add NAME URL [BRANCH]NAME podspec仓库的名称URL podspec仓库的git地址

    7、推送.podspec到specs仓库pod repo push REPO [NAME.podspec]REPO podspec仓库的名称,NAME podspec文件名,如果不写则默认取当前目录下的xxx.podspec文件。

    8、推送.podspec到cocoapods/specspod trunk register EMAIL [NAME]pod trunk push [PATH]

    9、Podfile导入pod,:git,:podspec,:path
    在source中设置specs仓库git路径source 'https://git.coding.net/marin-hc/FFSpecs.git'

    指向podspec文件pod 'spec1', :git => 'https://git.coding.net/xxx.git'

    指向本地的podspec文件的路径pod 'spec2', :podspec => '/Users/ff/xxx.podspec'pod 'Weexplugin', :path=>'./Weexplugin/'pod 'IGListKit', :path => '../../IGListKit.podspec'

    例如:pod 'XAspect', :path => './../'安装到Development Pods目录下

    10、查找podspec的路径
    pod spec which AFNetworking

    /Users/ff/.cocoapods/repos/master/Specs/a/7/5/AFNetworking/3.1.0/AFNetworking.podspec.json

    http://blog.wtlucky.com/blog/2015/02/26/create-private-podspec/

    podspec语法参考:
    https://guides.cocoapods.org/syntax/podspec.html

    pod命令参考:
    http://guides.cocoapods.org/terminal/commands.html#group_specifications

    podfile语法参考:
    http://guides.cocoapods.org/syntax/podfile.html

    http://tips.producter.io/shi-yong-cocoapods-jin-xing-tuan-dui-xie-zuo/

    11、pod package xx.podspec
    Mach-O universal binary with 5 architectures: [arm_v7: current ar archive] [arm_v7s] [i386] [x86_64] [arm64]
    --embedded--library
    --dynamicObjects-normal/arm64/MyKit normal arm64(1 failure)

    五、符号表/提取头文件

    1、class-dump

    用class-dump可以把未经加密的app的头文件导出来
    class-dump -H testClassDump.app -o test

    2、nm

    符号表可以提供应用软件及其动态加载的库中引用的函数、类、方法等信息
    显示目标文件的符号表,文件对象可以是静态库、动态库、编译目标文件、可执行程序等任何包含符号信息的文件类型

    3、otool

    查询依赖了哪些库、支持的架构信息、版本号

    相关文章

      网友评论

        本文标题:iOS 库研究

        本文链接:https://www.haomeiwen.com/subject/wgxwkxtx.html