The definition of ObjC confuses me a bit. It's said to be a superset of C - but which C? C89? C99? GNU-C-Something?
The definition of ObjC confuses me a bit. It's said to be a superset of C - but which C? C89? C99? GNU-C-Something?
Obj-C also includes the Foundation classes that were originally introduced with the OpenStep SDK in 1994 (NSObject, NSString, NSNumber, NSArray, NSRunLoop, NSAutoreleasePool, etc.).
Talking of OpenStep, after seeing some of those NeXT videos on HN the other day, I found a torrent of OpenStep 4.2 incl the dev tools. It's a VMware image and boots and runs just fine. Pretty nifty. Then I noticed OpenStep 5.0 redirects to Mac OS X on Wikipedia!
id foo = [self bar];
is the same as: id foo = self.bar;
which is also the same as: id foo = [self performSelector:@selector(bar)];
or: IMP barImp = [self methodForSelector:@selector(bar)];
id foo = barImp(self, @selector(bar); [1]
and finally: id foo = ((id)(id, SEL)objc_msgSend)(self, @selector(bar)); [2, 3, 4]
1. Because we're calling the IMP, or implementation, directly, we don't need a cast (like we do below, with objc_msgSend).2. Casting the function is optional, but, helps to prevent things like endian differences and your return value getting mangled when using the same code on PPC and Intel. Not too big of a deal anymore.
3. There are actually two other varieties of objc_msgSend, depending on your return type — specifically, floating point calls should use objc_msgSend_fpret and calls that return a struct should use objc_msgSend_stret.
4. I hope I got this cast right, I didn't try to compile it.
objc_msgSend(self, @selector(bar));
And: objc_msgSend(self, @selector(performSelector:), @selector(bar));
?They would both become:
objc_msgSend(self, @selector(bar));
However, your examples are basically explicitly passing a message (1 and 2), vs dynamically building a message to pass (3).For the second to work, the objc_msgCall function would really be:
objc_msgSend(self, @selector(performSelector:), @selector(bar));
(The first example is saying to self to call the selector (method) named 'bar'. The second example is telling self to call the method 'performSelector:' with an argument of 'bar'.)The runtime may or may not be smart enough to optimize this out. It has never been a bottleneck for me to bother looking into it, and I haven't come across anything to indicate one way or the other.