加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – 为什么将任何选择器发送到Nil对象什么都不做,但

发布时间:2020-12-16 05:51:53 所属栏目:百科 来源:网络整理
导读:有没有人知道为什么NextStep / Apple决定采用“方便的方法”,当传递一个Nil对象一个消息时,什么都不做,但是在传递一个被实例化的对象一个无效选择器时引发异常的“ Java方法” 例如, // This does "nothing"NSObject *object = Nil;[object thisDoesNothing]
有没有人知道为什么NextStep / Apple决定采用“方便的方法”,当传递一个Nil对象一个消息时,什么都不做,但是在传递一个被实例化的对象一个无效选择器时引发异常的“ Java方法”

例如,

// This does "nothing"
NSObject *object = Nil;
[object thisDoesNothing];

object = [[NSObject alloc] init];
// This causes an NSInvalidArgumentException to be raised
[object thisThrowsAnException];

所以一方面,我们有方便的没有检查Nil(假设我们不太在意方法调用的结果) – 但另一方面,如果我们的对象我们必须检查异常没有回应方法?

如果我不确定对象是否会响应,我必须:

@try {
    [object thisThrowsAnException];
} @catch (NSException *e){
    // do something different with object,since we can't call thisThrowsAnException
}

要么,

if([object respondsToSelector:@selector(thisThrowsAnException)]) {
    [object thisThrowsAnException];
}
else {
    // do something different with object,since we can't call thisThrowsAnException
}

(后者可能是更好的方法,因为如果对象是Nil,则选择器不会引发异常,因此您的代码可能不会按照您的要求执行).

我的问题是:
为什么苹果决定以这种方式实施?
为什么没有对实例化对象无法识别的选择器调用不会引发异常?
或者,为什么没有Nil对象引发异常,如果您尝试调用它的方法?

解决方法

我不能完全回答你的问题,但我可以回答你的一些问题. Objective-C允许您将消息发送到nil,因为它使代码更加优雅. You can read about this design decision here,我将窃取榜样:

假设您想要获取某人在办公室电话上拨打的最后一个电话号码.如果你不能发送消息到nil,你必须这样写:

Office *office = [somePerson office];
// Person might not have an office,so check it...
if (office) {
    Telephone *phone = [office telephone];
    // The office might not have a telephone,so check it...
    if (phone) {
        NSString *lastNumberDialed = [phone lastNumberDialed];
        // The phone might be brand new,so there might be no last-dialed-number...
        if (lastNumberDialed) {
            // Use the number,for example...
            [myTextField setText:lastNumberDialed];
        }
    }
}

现在假设你可以发送消息到nil(并总是没有回来):

NSString *lastNumberDialed = [[[somePerson office] telephone] lastNumberDialed];
if (lastNumberDialed) {
    [myTextField setText:lastNumberDialed];
}

至于为什么发送一个无法识别的选择器到一个对象引发了一个例外:我不知道肯定.我怀疑这是一个更为常见的bug,而不是无害的.在我的代码中,当我需要发送一个可选的协议消息(例如向代理发送一个可选消息)时,我只希望一个无法识别的选择器被忽略.所以我希望系统将其视为一个错误,让我在相对罕见的情况下显而易见,当我不希望它是一个错误.

请注意,您可以通过几种不同的方式处理您自己的课程中无法识别的选择器(在某种程度上).看看forwardingTargetForSelector :,forwardInvocation :,doesNotRecognizeSelector :,和resolveInstanceMethod:NSObject的方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读