• 扩展方法,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,注意原有引用库文件


  • 相关阅读:
    INFORMATION_SCHEMA.INNODB_LOCKS
    INFORMATION_SCHEMA.INNODB_TRX 详解
    zabbix 通过key 获取
    匿名hash
    [] 和{} 匿名引用
    perl 初始化Hash
    9.2 数组的散列
    数组的数组
    RMAN恢复目录
    验证备份前设置CONFIGURE CONTROLFILE AUTOBACKUP ON/OFF; 的区别
  • 原文地址:https://www.cnblogs.com/GoGoagg/p/2128711.html
Copyright © 2020-2023  润新知