Re: Is _objc_flush_caches_(Class) necessary to swizzle methods?
Re: Is _objc_flush_caches_(Class) necessary to swizzle methods?
- Subject: Re: Is _objc_flush_caches_(Class) necessary to swizzle methods?
- From: Glenn Andreas <email@hidden>
- Date: Fri, 24 Sep 2004 11:18:27 -0500
At 11:56 AM -0400 9/24/04, DumberThanDanQuayle wrote:
Glenn, thanks for the response.
On Sep 24, 2004, at 9:55 AM, Glenn Andreas wrote:
At 4:47 AM -0400 9/24/04, DumberThanDanQuayle wrote:
Does anybody know what the story with "_objc_flush_caches_(Class)"
and method swizzling really is?
From my understanding delving the depths of the runtime,
_objc_flush_caches_ is needed because the runtime maintains cache
of recent methods & imps used when dispatching. So once it figures
out that [foo something] is at 0x123400, it keeps that in the
cache for Foo.
If you change foo something to point to 0x567800, the cache will
still refer to the old version, so the next time you call [foo
something] 0x123400 gets executed, and not your new 0x567800.
If it is a method that has never been called, you could probably
get away without calling it.
Great, now I know what _objc_flush_caches_(Class) does and that it
should have nothing to do with my runtime's "strangeness" because I
am method swizzling to achieve something like multiple inheritance
and I am attempting it in +initialize. So my instance methods
should have never been called by that time.
The source for the runtime is part of Darwin, so you can "use the
source, Luke" (it's filled with all sorts of interesting tidbits,
too).
More importantly, though, is that method swizzling is probably not a
good strategy to achieve something like multiple inheritance. Not
the least problem is that if you are attempt to have one class "look"
like another class, it will need to have the same instance vars
(instance vars are referenced as offsets from "self", so if you use a
method for class Foo and the receiver is actually class Bar, the code
thinks that you have Foo's ivar structure when you have Bar's ivar
structure - perhaps this was the debugging problem you saw before?)
On the other hand, method forwarding and its friends can achieve a
great deal of the functionality that you may be looking for (and
provides a way to simulate changing the class heirarchy at runtime -
after all, the delegate of an NSWindow is used to make that window
behave like something other than the default NSWindow).
OTOH, I've never seen a problem with inheritence/ivars when doing
this (since that information doesn't use any of the method dispatch
cache anyway).
The type of runtime "strangeness" I am now continuing to experience
is not something simple like the old method is called instead of the
new one. I am talking about the bizarre, like a case of an infinite
loop being generate when calling [super someMethod] and somehow the
runtime decides the receiving method is in a _subclass_ (which in
turn calls [super someMethod]). My latest oddity is the swizzling
of two classes mixes up their "init" methods. It is as if my entire
runtime is being randomly swizzled (or at least those of classes
related to being modified).
It does sound like something painful is happening to your runtime.
This brings me to my next question. Is +initialize a bad place to
swizzle for some reason? Should I try waiting until all classes
have been initialized first? Moreover should I type-check in
+initialize so that subclasses do not redundantly swizzle methods?
One potential problem is categories are often loaded later, which
will replace this.
And yes, you should probably check self == [MyClass class] to avoid
getting initialize messages from subclasses.
Another concern I have is that the CocoaDev page I referenced also
reassigns Method->method_types when swizzling. I suppose this not
necessary useless the arguments required for the methods being
swapped are actually different, but I am not sure.
Changing method types when swizzling - ew. That sounds like very bad
mojo (since the compiled code was generated for different parameter
types, and suddenly, if you've got something else...)
--
Glenn Andreas email@hidden
<http://www.gandreas.com/> oh my!
Mad, Bad, and Dangerous to Know
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden