zoukankan      html  css  js  c++  java
  • 扩展方法,ObjectiveC


    今天主要为NSString类扩展一个类方法

    为了在此blog简化讲解过程,类方法名称=PrintToConsole,此方法在此仅仅是模拟函数

    在实践中,遇到两个问题。

    分别描述实践过程。

    1、新建文件ExtString.h,ExtString.m
    @interface NSString(ExtString)

    +(void) PrintToConsole:(NSString *)plainText;

    @end

    实现:
    +(void) PrintToConsole:(NSString *)plainText
    {
        NSLog(@"%@" ,plainText);
    }

    2、新建一个项目TestA,添加上述文件
    在main函数中,添加此头文件,
    NSString *test = @"The boy is good";
    [NSString PrintToConsole:test];

    此项目TestA运行正常,输出The boy is good。

    3、新建静态库libUtils,添加ExtString两个文件
    编译通过

    4、新建一个项目TestB,在Build设置中添加静态库libUtils
    同样在main中添加同样的测试代码

    现在出现了错误:unrecognized selector sent to XXXXXX

    分析:TestA运行正常,TestB出现异常,说明要么TestB没有找到静态库,要么静态库的配置和输出不正确
    按项目的文件存在来看,TestB应该找到静态库

    由于对扩展方法的使用经验不足,我先建议使用普通类的方式先实现

    5、在libUtils,新建两个文件ConsoleObj.h,ConsoleObj.m
    @interface ConsoleObj

    +(void) PrintToConsole:(NSString *)plainText;

    @end

    实现:
    +(void) PrintToConsole:(NSString *)plainText
    {
        NSLog(@"%@" ,plainText);
    }

    在TestB项目中,先屏蔽原有测试,输入新的测试代码:
    [ConsoleObj PrintToConsole:@"The second Test code"];

    编译成功,运行出现新的错误:
    does not implement methodSignatureForSelector: -- trouble ahead

    啊,why?

    细细想下以前的代码,没有出现问题呀,为什么这次会出现错误?
    回溯检查代码ConsoleObj的代码,仅仅发现一个地方和以前不一样,少了父类NSObject,这个差异的产生是由于直接拷贝原来代码ExtString修改而来的。

    好,修改此代码
    @interface ConsoleObj:NSObject

    +(void) PrintToConsole:(NSString *)plainText;

    @end

    编译libUtils,再运行测试,没有错误了

    现在的情况是:
    测试项目调试静态库普通类,没有问题【TestB】
    测试项目调试项目自带的扩展方法,也没有问题【TestA】
    测试项目测试静态库的扩展方法,出现问题unrecognized selector sent to XXXXXX

    没有找到问题所在,借用google,baidu
    发现网上的方案:在XCode4下,配置编译选项Other Linker Flags,加入-all_load
    (PS:-all_load 告知编译器 所有lib都需要加载)


    好,按此方案配置TestB,开启原有测试代码,发现OK了

    PS,还有点插曲,我实际的项目中静态库又加了系统自带的库,比如libz等
    在测试项目中,需要加这些自带库,不然编译通不过。

    最后,要提醒的是:
    1、Objective-C自建类的超类一定是NSObject,所以不要省略:FatherClass
    一定是这样的:
    @interface SonClass:FatherClass
    @end

    2、扩展方法出现错误unrecognized selector sent to,优先考虑-all_load配置,再考虑内存释放

    3、用了-all_load,注意原有引用库文件


  • 相关阅读:
    (转)Zipalign——Android apk优化工具
    (转)Android 数字证书详
    (转)ant深入浅出
    (转)Java调用Ant API用法
    (转)Java 代码调用ANT
    (转) Android如果对APK进行加密,提高反编译难度(思路)
    (转)Ant自动打包
    (转)Ant build.xml中的各种变量,使用系统环境变量
    (转)JAVA调用脚本
    (转)Android 编译,打包、签程名详细教
  • 原文地址:https://www.cnblogs.com/GoGoagg/p/2128711.html
Copyright © 2011-2022 走看看