[Prev][Next][Index][Thread]
Re: Objective C bridge
I have read Apple's documentation of the Java bridge, but it is way too
skimpy on details to use as a model.
(We'll need some vocab. I will use "Obj C stub", "Dylan stub", and
"bridge class" for the combination of the two. I'll use "me" or "we"
indiscriminately.)
The keys were the flexibility of the Obj C run-time and the dynamicism
of Dylan. I can create Objective C and Dylan stubs at run-time, use
plain C as an mediating interface, vivisect the Objective C classes, and
make the Dylan stub transparent.
The bridge class will have an interesting life cycle. I expect it could
be instantiated either on the Dylan or Obj C side of things.
If Obj C instantiates the bridge class, it'll be the framework doing it.
I'm assuming the user won't be writing any Objective C code of his own.
I think we can trust the framework to properly allocate and release the
Obj C stub. So long as the Obj C stub exists, the Dylan stub should
also. That means we need to keep a reference around on the Dylan side of
things, to keep the Dylan stub from getting garbage-collected. When the
framework finally releases the Obj C stub, we can remove the Dylan
reference.
If Dylan instantiates the bridge class, then we just need to keep an
extra Dylan reference around only if the Obj C side retains the Obj C
stub, and release that reference when all the Obj C references are also
released.
The bridge class will have instance variables. It will keep those
variables in the Obj C stub, since Obj C code will need direct access to
the variables. The Dylan stub can access the variables through setters
and getters that deal directly with the Obj C object structure.
The bridge class will also have methods, some of which will be inherited
from an Objective C superclass. Those inherited methods will be
accessible to Dylan code via objc_msgSend. Non-inherited or overridden
methods will be written in Dylan, and exposed to Obj C code via C
callbacks.
So basically, that's the plan. I don't think there are actually that
many factors to consider here.
I'd like the syntax to look something like this, but I'm not sure
obj-c-bridge-definer will be evaluated at run-time or compile-time. For
this concept, it'll need to be run-time. Additionally, I don't have as
much practice with Dylan as I'd like, so this syntax may prove
impractical.
---------------------------------------------------------------------
// Sub-class of NSView with Dylan-specific instance variables.
define class <my-subview> (<obj-c-bridge>)
slot my-slot;
end class;
// An overridden NSView method.
define method draw-rect (view :: <my-subview>, rect :: <rect>)
view.frame := rect; // "frame" is inherited Obj-C variable
view.super-set-background ($red);
end method;
// Link the <my-subview> class to the Objective C runtime. This macro
// will add methods and slots to the Dylan class. I think the class
// should contain <function> slots to mimic the method/variable combo
// of Obj C classes and allow delegates.
define obj-c-bridge <my-subview> ("NSView")
// Declare Obj C super-class functions to use, but not override.
inherit "- setBackground:(NSColor)" as super-set-background;
// Exported Dylan functions
export draw-rect as "- drawRect:(NSRect)";
end;
begin
...
end;
----------------------------------------------------------------------
I've read some of the issues you guys have posted.
In an earlier thread by Rob and, um...Dennis De Mars, they mentioned a
problem with the Obj C function names and Dylan functions with keyword
parameters. Basically, all methods on a generic function must use the
keyword params declared in the generic, but Obj C doesn't require any
consistency in keyword parameters. Rather than struggle with this, I can
simply allow different method names on the Obj C and Dylan sides,
specified by the programmer.
Rob wrote:
> > * I want to be able to create an Obj C stub that fits in the Obj C
> > class hierarchy, so I can subclass NSWindowController (for example).
>
> It's more of a facade, I think. See how Apple make proxies for Java
> Objects. I came up with an incredibly overblown solution using NSProxy,
> but a simple facade is much better, I think. :-) I can't figure out how
> Objective-C classes are added to the dispatch table in the Objective-C
> runtime. I think it's runtime-specific. :-(
It may well be. The runtime offers classes for dispatching messages,
adding classes, finding classes by name, retrieving variables and
methods of a class by name, and editing a class's method list. Looks
easy for the OS X runtime.
> > * Methods of the Obj C stubs should map to Dylan methods.
>
> If each Obj-C method calls a Dylan callback, no problem. It would be
> harder, but still possible, to crack the Objective-C method name mangling
> scheme and add Dylan callbacks to the hashtable Objective-C uses to look
> up methods.
I think that's overkill. I bet objc_msgSend will do the job nicely, once
the stub class is installed into the run-time.
> > * Obj C exceptions should map to Dylan exceptions. This'll be easy.
>
> How will you do this? I'm interested.
This is really easy. I assume the user won't be writing Objective C
code, so any Obj C exceptions will be thrown by the framework and
percolate all the way to the top. I can change the last-resort exception
handler function. I'll just redirect that to an exported and
C-compatible Dylan function, which can translate the NSException to some
<obj-c-exception> object and signal it. Then the normal Dylan
exception-handling system takes over.
References: