The new syntax is a bit more verbose, however it no longer requires importing a vocabulary for each class you intend to use. Instead, you use this syntax:
NSObject -> alloc -> init
This is in fact equivalent to the following, since
->
is a parsing word:NSOject "alloc" send "init" send
Calling methods in a superclass is done in a similar way:
SUPER-> dealloc
"dealloc" send-super
The compiler transforms the calls to
send
; in fact, the lookup of the selector is done at compile time, and the compiler turns the above snippet into something like this:NSObject
T{ selector f "alloc" f } selector G:78604
T{ selector f "init" f } selector G:78604
The
selector
object caches the Objective C selector (a sort of internalized string, analogous to a Lisp symbol). The gensym is the cached message sender which only depends on the arglist. Here is a typical definition:"id" f "objc_msgSend" { "id" "SEL" } alien-invoke
So the new binding style uses less space in the image, and is no slower since in the end the same code is generated, except with less redundancy and duplication. There is one disadvantage, though: if two imported methods have the same selector but different argument or return types, they will clash and you will not be able to send one of the two methods using
send
or send-super
. There are various ways around this; either make method dispatch slower and look up arguments at runtime (this also makes it harder, but not impossible, to make it compile) or provide an alternative form of send
, perhaps send*
, which takes as class name and can be used in the case of clashes.
No comments:
Post a Comment