Re: Bridging (was Re: A CFStringRef that throws EXC_BAD_ACCESS)
Re: Bridging (was Re: A CFStringRef that throws EXC_BAD_ACCESS)
- Subject: Re: Bridging (was Re: A CFStringRef that throws EXC_BAD_ACCESS)
- From: Simon Stapleton <email@hidden>
- Date: Sun, 20 Oct 2002 22:27:24 +0200
On Sunday, Oct 20, 2002, at 11:25 Europe/Paris, Finlay Dobbie wrote:
On Sunday, October 20, 2002, at 02:19 am, Timothy Ritchey wrote:
So, the CFXMLNode you are given is already set up to be used as a
full-fledged class in Objective-C, since the _isa pointer is the only
thing needed to make a structure into an Obj-C class.
Okeydokey. That's out then. Poop.
CFXMLNode has all the fix'ns for bridging. You would have to create
your own class definition that had the right instance variables to
match the existing CF structure.
This is not how bridging is accomplished in CoreFoundation/Foundation,
as far as I can see.
Indeed
All the other CF classes have funky stuff all over them to cope with
the bridging, like CF_OBJC_FUNCDISPATCH0 and CF_IS_OBJC. I still don't
quite grok how all the bridging works, but it's definitely a scary
beast.
And ain't that the truth.
As far as I can tell, the way it works is this - feel free to slap me
about if I'm way off base here, but...
CoreFoundation has a table of pointers to ObjC classes, called
__CFRuntimeObjCClassTable, which is the private symbol I was hinting at
in my previous email. For bridged classes, the entry at the index
given by CFxxxGetClassID() contains a pointer to the ObjC class that is
bridged. For other classes, it contains a pointer so some placeholder
class (NSCFType, I think).
The class being pointed at in this table, as far as I can tell by
poking around, can't have any instance variables, but I'm not sure of
that.
You will also notice (using FSA, class-dump, or equivalent) that
NSObject defines a method called _cfTypeID, which has a default
implementation which returns 1 (NSCFType again). Bridged classes
override this and return the relevant CFTypeID.
It seems from my experiments so far that all you need to do to bridge
is as follows:
Hack the class table before any objects of the relevant types have been
created - see function __CFInitialize() in CFRuntime.c, it seems to
imply that Very Bad Things(tm) will happen if you don't do this early.
Make sure your class has no instance variables - do everything through
the CF instance variables. It should be noted, I've yet found no way
of actually getting to them besides using the CF methods and passing in
self cast to the relevant type...
Implement at least -_cfTypeID, and have it return the relevant type.
From a brief perusal of the CFURL sources it looks like, in some
cases, there is a check for CF_IS_OBJC, and if there is, it creates a
real CF copy of the URL and manipulates that, and in other cases,
CF_OBJC_FUNCDISPATCH is used to call the equivalent obj-c method if it
exists. In fact, it looks like in a lot of cases, there are *STILL*
two implementations of methods: one on the obj-c object, and one in
the CF function, with the CF function just calling the obj-c method if
the object supplied is an obj-c object. Yuck.
Yeah. I'm still not sure what all that's about. The CF_IS_OBJC things
checks the aforementioned private table and compares the isa from the
CF object to the class in the table, or something similar. It's all
very nasty, but so far I haven't had to worry about any of that.
Simon
--
PGP Key Id : 0x50D0698D
--
If the answer isn't obvious, the question is a distraction. Go find an
easier question.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.