Re: How is @selector resolved at compile time ?
Re: How is @selector resolved at compile time ?
- Subject: Re: How is @selector resolved at compile time ?
- From: Greg Titus <email@hidden>
- Date: Thu, 26 Jul 2001 01:10:02 -0700
On Wednesday, July 25, 2001, at 08:59 PM, Erik M. Buck wrote:
The following assembly code is taken from the output of the test.
__OBJC_SELECTOR_TABLE: obviously holds the selector values. How are
these
selector values merged with selector values from other files and other
frameworks. I assume the magic is in __OBJC_MODULE_CONSTRUCTOR:
when it calls ___objc_execClass. What does ___objc_execClass do
exactlt ?
If you have a global symbol like "errno" that you declare "extern" and
use in a whole lot of different libraries, how does the linker manage to
make all those references point to the same variable...?
That's an oblique way of saying: the selectors are uniqued the same way
any other external symbol is uniqued by the linker. The code
"@selector(foo)" generates assembly for a constant address, which is set
to the correct uniqued value at link time, the same way that use of the
global variable "errno" generates assembly for a constant address, which
is set to the correct uniqued value at link time. That's the sort of
thing that linkers do...
It is slightly different because there isn't a single location where the
selector is defined, with all other object files having references
instead of definitions. With selectors, every object file that uses the
selector has a full definition of it - but this makes the task of the
linker _easier_, not harder, since it can use any (single) definition
instead of searching for whichever compilation unit the real definition
is in.
So no, there is absolutely no run-time lookup or overhead for
@selector().
{
IMP function = [@"" methodForSelector:@selector(class)];
int i;
time2 = [NSDate timeIntervalSinceReferenceDate];
for(i = 0; i < 10000000; i++) {
(*function)(@"", @selector(class));
}
time3 = [NSDate timeIntervalSinceReferenceDate];
}
The @selector() generates one instruction for loading a constant address
into a register. If the optimizer doesn't completely suck, that single
instruction gets hoisted out of the loop and is performed only once
before the loop starts. So the generated code should be exactly the same
as your third loop where you assign the result of @selector to a local
variable before the loop starts.
Hope this helps,
--Greg