Por que é que enviar qualquer seletor para um objeto Nil não faz nada, mas enviar um seletor “inválido” para qualquer NSObject gera uma exceção?

Alguém sabe por que NextStep / Apple decidiu tomar o "método conveniente" de não fazer nada quando passar um objeto Nil uma mensagem, mas o "método Java" de levantar uma exceção ao passar um objeto instanciado um seletor inválido?

Por exemplo,

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

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

Então, por um lado, temos a conveniência de não ter que verificar Nil (assumindo que não nos importamos muito com o resultado da chamada do método) - mas, por outro lado, temos que verificar uma exceção se o nosso objeto não responde a um método?

Se não tenho certeza se o objeto responderá, eu preciso:

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

Ou,

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

(Esta última é provavelmente a melhor maneira de fazer isso, já que se o objeto for Nil, o seletor NÃO aumentará uma exceção, assim seu código pode não se comportar da maneira que você deseja).

Minha pergunta é: por que a Apple decidiu implementá-lo dessa maneira?
Por que não ter a chamada seletora não reconhecida para um objeto instanciado não gerar uma exceção?
Como alternativa, por que o objeto Nil não gera uma exceção se você tentar chamar um método nele?

questionAnswers(3)

yourAnswerToTheQuestion