• 【iOS】使用respondsToSelector方法前是否需要对方法调用者进行判空操作?


    前情

    iOS开发中,经常需要将事件传递给上层代理去处理,这个时候会用到『respondsToSelector』去检测上层代理是否有实现对应的方法,如果实现了,才会去调用。

    - (void)methodExample {
        if ([self.delegate respondsToSelector:@selector(cell:didClickOnUserInfo:)]) {
            [self.delegate cell:self didClickOnUserInfo:self.item];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    而项目中,很少直接调用respondsToSelector,而是调用了一个宏。

    #define PackageRespondsToSelector(delegate,selector)  ((delegate) && ([delegate respondsToSelector:selector]))
    
    - (void)methodExample {
        if (PackageRespondsToSelector(self.delegate, @selector(cell:didClickOnUserInfo:))) {
            [self.delegate cell:self didClickOnUserInfo:self.item];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以从宏的定义里发现,实际上就是在调用系统respondsToSelector方法前,先对方法调用者delegate进行了一个判空操作。

    但实际上我们开发时是否需要这个判空操作?

    实测

    - (void)method1 {
        if ([self.delegate respondsToSelector:@selector(cell:didClickOnUserInfo:)]) {
            [self.delegate cell:self didClickOnUserInfo:self.item];
        }
    }
    
    - (void)method2 {
        if (self.delegate && ([self.delegate respondsToSelector:@selector(cell:didClickOnUserInfo:)])) {
            [self.delegate cell:self didClickOnUserInfo:self.item];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    当 self.delegate 不为 nil 时,method1 和 method2 效果肯定是等价的;
    当 self.delegate 为 nil 时:
    ** 先看method2,self.delegate为nil,都不会去执行后面的判断,而直接返回NO。
    ** 再看method1,nil调用respondsToSelector方法,会返回什么?

    直接写个demo,run起来后,发现 fanHuiZhi 为 NO。可知nil调用respondsToSelector方法,会返回NO。

    - (void)methodDemo {
       self.delegate = nil;
       BOOL fanHuiZhi = [self.delegate respondsToSelector:@selector(cell:didClickOnUserInfo:)]
       if (fanHuiZhi) {
           [self.delegate cell:self didClickOnUserInfo:self.item];
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    参考 https://www.jianshu.com/p/11dca953f962 中的说法。nil调用方法 返回什么,取决于该方法的返回值类型。respondsToSelector方法的返回值类型为BOOL,所以[nil respondsToSelector:xxx]会得到NO

    故可以知道,self.delegate 为 nil 的时候,if 判断都是 NO,不会去调用代理方法,故 method1和 method2等价。
    不论 self.delegate 是否为 nil,method1和 method2都是等价的,调用封装的宏PackageRespondsToSelector和直接调用系统api respondsToSelector是一样的。

    结论:使用respondsToSelector方法前不需要对方法调用者进行判空操作

  • 相关阅读:
    手写Promise
    2022年四川省职业院校技能大赛网络搭建与应用赛项
    金仓数据库 KingbaseES 与 Oracle 的兼容性说明(4. SQL)
    尚硅谷设计模式学习(十三)代理模式
    常用H标签的补充:html5
    appnium环境搭建
    腾讯云服务器简介和使用流程
    游戏工作中用到的一些第3方软件和作用
    C语言-函数
    Spring Data JPA 之 @Entity 回调方法
  • 原文地址:https://blog.csdn.net/weixin_47128888/article/details/133346420