Why is it that sending any selector to a Nil object does nothing, but sending an “invalid” selector to any NSObject raises an exception?

前端 未结 3 607
囚心锁ツ
囚心锁ツ 2020-12-16 17:47

Does anyone know why NextStep/Apple decided to take the \"convenient method\" of doing nothing when passing a Nil object a message, but the \"Java method\" of raising an exc

3条回答
  •  自闭症患者
    2020-12-16 18:49

    I can't fully answer your question, but I can answer part of it. Objective-C allows you to send a message to nil because it makes code more elegant. You can read about this design decision here, and I will steal its example:

    Let's say you want to get the last phone number that some person dialed on her office phone. If you can't send messages to nil, you have to write it like this:

    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];
            }
        }
    }
    

    Now suppose you can send messages to nil (and always get nil back):

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

    As for why sending an unrecognized selector to an object raises an exception: I don't know for sure. I suspect that it's far more common for this to be a bug than to be harmless. In my code, I only want an unrecognized selector to be silently ignored when I need to send an optional protocol message (e.g. sending an optional message to a delegate). So I want the system to treat it as an error, and let me be explicit in the relatively rare case when I don't want it to be an error.

    Note that you can tinker (to some extent) with the handling of unrecognized selectors in your own classes, in a few different ways. Take a look at the forwardingTargetForSelector:, forwardInvocation:, doesNotRecognizeSelector:, and resolveInstanceMethod: methods of NSObject.

提交回复
热议问题