• 创建含有category的静态库,selector not recognized的解决方案


    一、异常的原因

    在连接一个含有category的静态库的时候,往往会得到一个运行时exception “selector not recognized”。

    这是由于 UNIX的静态库实现、linker和Objective-C的动态结构三者之间的问题引起的。

    Objective-C并不为每个函数定义linker symbol,它只为每个class生成linker symbol。(objc的动态结构)

    如果你为一个已存在的class创建了category,那么linker并不知道要将原始class实现和category实现联系起来。这就导致了最终程序中的对象没法响应category中的方法。

    要解决这个问题,只要在build静态库时,加上linker flag “-ObjC”即可(在64位osx上和iOS程序上,这样做还不够),这个flag告诉linker将每个定义了class或者category的对象文件都载入静态库。

    二、iOS程序还需要做的

    用xcode4.3创建lib时,-ObjC这个flag默认是有的(之前的版本不记得了,好像4.x版本的都会默认带这个参数),但是最终程序还 是会抛这个异常,这是因为linker的bug,对于64位osx程序和iOS程序,这个bug导致只包含category而不包含class的文件没法 从静态库中加载。

    所以,apple建议我们为要最终程序的linker加上-all_load或者-force_load参数。

    -all_load选项强制linker加载所有包中的所有对象文件,即使文件中没有Objective-C代码也加载。-force_load是 从Xcode3.2开始有的,它使得linker获取包加载的控制权,每个-force_load参数后面都必须跟上一个包的路径,然后这个包的所有对象 文件都会被加载。

    懒人使用-all_load,勤快人使用-force_load。。。

    -force_load $(BUILT_PRODUCTS_DIR)/<library_name.a>

    但是这样始终不好,因为这两个选项都可能导致不必要的代码被加载。

    三、更好的方法

    Three20库给出了一个宏:

    #define TT_FIX_CATEGORY_BUG(name) @interface TT_FIX_CATEGORY_BUG_##name @end
                                      @implementation TT_FIX_CATEGORY_BUG_##name @end

    为每个只包含category的文件的category实现前面加上这样一个宏(定义一个空的class),此时不再需要-all_load或者-force_load,因为不存在只包含category的文件。linker的bug也就无从体现。

    转载:http://www.dreamingwish.com/dream-2012/%E5%88%9B%E5%BB%BA%E5%90%AB%E6%9C%89category%E7%9A%84%E9%9D%99%E6%80%81%E5%BA%93selector-not-recognized%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88.html

  • 相关阅读:
    react 滑动删除组件
    004-Java进制转换
    003-JavaString数据类型
    002-Java数据类型
    001-Java命名规范
    【leetcode】804
    【MySQL】基本语句
    【python】
    hiveSql常见错误记录
    【数据库】-基本特性
  • 原文地址:https://www.cnblogs.com/bu779783251/p/3168972.html
Copyright © 2020-2023  润新知