objective-c – 为什么将任何选择器发送到Nil对象什么都不做,但是向任何NSObject发送“无效”选择器会引发异常?

前端之家收集整理的这篇文章主要介绍了objective-c – 为什么将任何选择器发送到Nil对象什么都不做,但是向任何NSObject发送“无效”选择器会引发异常?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有没有人知道为什么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方法.

原文链接:https://www.f2er.com/c/113475.html

猜你在找的C&C++相关文章