views:

103

answers:

2

There are some functions which take as an argument @selector(methodName). I used NSLog to find out what @selector is, and it returns an integer. It looks like a PID, but when I ran ps ax that PID could not be found. What does that integer represent and why do we have to use @selector all the time instead of just passing the method name?

+10  A: 

@selector() is a compiler directive to turn whatever's inside the parenthesis into a SEL. A SEL is a type to indicate a method name, but not the method implementation. (For that you'd need a different type, probably an IMP or a Method) Under-the-hood, a SEL is implemented as a char*, although relying on that behavior is not a good idea. If you want to inspect what SEL you have, the best way to do it is to turn it into an NSString* like this:

NSLog(@"the current method is: %@", NSStringFromSelector(_cmd));

(Assuming you know that _cmd is one of the hidden parameters of every method call, and is the SEL that corresponds to the current method)

The Objective-C Programming Language Guide has much more information on the subject.

Dave DeLong
+1 for detailing.
hib
`SEL` is not actually a C string anymore; it points to an opaque type defined in libobjc. The first member is a C string for compatibility purposes, but you're not supposed to rely on that; proper code uses `sel_getName` to actually access the C-string member, or `NSStringFromSelector` to create an NSString from it.
Peter Hosey
@Peter thanks for the clarification.
Dave DeLong
A: 

I think looking at the Objective-C implementation might be good for an understanding:

A selector is an integer value. But its type is different from normal C integer values so you can't assign them.

The selector name like "methodName" is the string that uniquely represents a name for this integer.

Other languages and systems call this unique program wide string to integer mapping an atom (Windows) or quark (GTK).

Objective-C keeps all functions for a class inside a hashtable. The hashtable key is an integer. The Objective-C runtime library looks up the hashtable on every method invocation. Without the unique integer number it would be much slower to do this critical lookup.

A selector is not an opaque pointer to a structure anymore. With MacOSX 10.6 the obj_send runtime function which implements the Objective-C method invocation is using an arithmetic operation on the selector at the beginning to find out if it is a retain, release, autorelease message and do something in this special cases. For example simply return in case you are using the garbage collector.

Lothar
Um, the “integer operation” in question is simply a comparison to a known value, which is the same for integers and pointers. At the assembly level, they’re the same thing.In actuality, SELs are still C string pointers internally in all Apple runtimes. (They’re a struct in the gcc and GNUstep runtimes.) However, they are declared as `typedef struct objc_selector *SEL` to create an opaque type, and the implementation may change the meaning at any time.
Ahruman
In this case a selector should point to a valid memory location. Do they? And what GNUstep does isn't relevant it so out of the league.
Lothar
I can't find the article anymore but if they are simple pointers how can a single comparison be a fast path branch for 3 different selectors? There need to be more behind this in MacOSX 10.6
Lothar
Lothar: If they didn't point to valid memory, you couldn't print them as C strings. As for how message dispatch works, see bbum's tour of objc_msgSend: http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/
Peter Hosey