[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
NSInvocation weirdness
From: |
David Chisnall |
Subject: |
NSInvocation weirdness |
Date: |
Sun, 23 Nov 2008 13:40:40 +0000 |
There is one piece of Objective-C I passionately detest, and that is
that it allows you to trivially call methods with the wrong
(structural) types if you use the same selector name in two unrelated
bits of code.
Unlike Apple, we have the opportunity to do something about this,
since the compiler fills in what it thinks are the types for a method
at compile time, allowing some sanity checking.
I am now seeing some strange behaviour in NSInvocation related to
this. If you send a message with one selector to an object expecting
another then you get a runtime abort which is hard to track down. The
issue can be seen in this snippet:
- (id) methodSignatureForSelector:(SEL)aSel
{
NSMethodSignature *s = [t methodSignatureForSelector:aSel];
NSLog(@"%s == %s", [s _methodTypes], sel_get_type(aSel));
return s;
}
In a simple example, I sent a -play message to an object via a proxy.
The object implemented:
- (void) play;
But the compiler guessed:
- (BOOL) play;
Running this code, I get:
2008-11-23 13:31:15.728 Music[8647] address@hidden:4 == address@hidden:4
vacall: va_start type 3 and va_return type 0 disagree.
Abort trap: 6 (core dumped)
Can we insert a assert into NSObject's methodSignatureForSelector to
check for this? Sometimes sel_get_type(aSel) will be NULL (e.g. if
the method was called via @selector()), but in this case there's
nothing we can do other than assume that the programmer knows what he
or she is doing.
Obviously this would come with a small performance penalty, but
forwarding invocations is already around 300 times slower than a
direct message send and this would make debugging certain categories
of problem a lot easier if people got a friendly 'method %s called
with incorrect signature' error.
David
- NSInvocation weirdness,
David Chisnall <=