[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: GSObjRuntime patches...
From: |
David Ayers |
Subject: |
Re: GSObjRuntime patches... |
Date: |
Wed, 09 Jun 2004 11:03:15 +0200 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.7) Gecko/20040514 |
Marc Ordinas i Llopis wrote:
Hi, everyone,
It would be really, really helpful for everyone else if people with CVS
write permission would at least try to describe the changes they commit.
Adam Fedor's gnustep-cvs hack certainly does help, but it's not
sufficient to track what's going on if commiters don't explain it to the
list(s).
Hello Marc,
I tend to agree. I was hoping that in this case the documentation which
was part of the patch was sufficient. But I guess it could use some more
introduction. So here's the long story...
My concrete problem was that Foundation implements certain categories
that are also implemented in GDL2. Now category precedence is undefined
by ObjC and in fact the GDL2 categories were pretty consistently ignored
on Cocoa in one particular application. But for GDL2 to work, we need
to make sure our categories are active.
First step was a way to identify the method list which corresponds to my
category. For this I implement a dummy method in my category and use
the new:
GSMethodList
GSMethodListForSelector(Class class,
SEL selector,
void **iterator,
BOOL searchInstanceMethods);
function to retrieve the list.
(Note that instance and class methods are in separate method list, so if
you have both instance and class methods you'll need to handle instance
and class methods separately.)
Second I remove the method list from from class with:
void
GSRemoveMethodList(Class class,
GSMethodList list,
BOOL fromInstanceMethods);
and add it again with:
GSAddMethodList(Class class,
GSMethodList list,
BOOL toInstanceMethods);
as this function should add the list in such a way that it becomes the
"active" method list and there for these methods will take precedence.
For finer granularity (manipulating method structures within a list) you
can use:
GSMethod
GSMethodFromList(GSMethodList list,
SEL sel,
BOOL isFree);
Which should return the "active" implementation of a method and then you
can start exchanging the pointers in the struct objc_method pointed to
by GSMethod.
Note that after any runtime manipulations like this, the class caches
should be cleared by calling:
void
GSFlushMethodCacheForClass (Class class);
In repository driven applications (or large GDL2 applications that have
lots of similar methods like standard object accessor methods with
common offsets yet different ivars) it can be of interest to share
implementations independent of class hierarchy and create method lists
at runtime.
For this you can use:
GSMethodList
GSAllocMethodList (unsigned int count);
to create a method list which my contain count methods. Then you start
filling the method list with:
void
GSAppendMethodToList (GSMethodList list,
SEL sel,
const char *types,
IMP imp,
BOOL isFree);
Where "imp" can be a pointer from an implementation from a template
class or even a function (which must take the hidden parameters self and
_cmd).
To complete the API I added:
BOOL
GSRemoveMethodFromList (GSMethodList list,
SEL sel,
BOOL isFree);
Actually GSObjCAddClassBehavior needs similar functionality when copying
behavior from one class to another. It also needs to take care not to
override methods that are already implemented in the class and certain
special cases like +initialize and +load. After the release of base,
I'll update GSObjCAddClassBehavior to use the new functions.
I hope you can get the rest of the information from the documentation.
How's that?
Cheers,
David