Method Swizzling reimplemented
Posted by: Kevin Ballard in Cocoa, Programming, tags: Cocoa, Method Swizzling, objc, ProgrammingMethod Swizzling is one common technique of people writing hacks, such as Safari Plugins. Unfortunately, it’s always suffered from a flaw, wherein swizzling inherited methods affects all classes which inherit that method (including the base class), rather than the intended subclass. This problem is discussed on the CocoaDev Method Swizzling page.
As part of writing YubNubSearch, I decided to solve this problem.
First I looked into dynamic subclass generation + posing. Unfortunately, this has a big problem. In
this technique, calling the original implementation would naturally be done through a [super foo] call.
Unfortunately, when the compiler sees super, it hardcodes a reference to the superclass at which to
start the search. This means you cannot write this code in, say, a category on NSObject, then pull up the IMP
into a dynamically-generated subclass and have it work. So that throws out that idea.
The other idea I had, which I eventually went with, was to copy inherited methods into the subclass that you wish to swizzle, before swizzling. It turned out to be fairly easy, and still has the same semantics as the old, flawed technique for calling the original implementation.
You can download my implementation here.
Entries (RSS)
January 2nd, 2007 at 6:56 am
Excellent idea. Hopefully the same idea can be implemented with the new API in Leopard as well.
January 2nd, 2007 at 2:28 pm
Once I have documentation about the API changes in Leopard I’ll look into it. Unfortunately right now, while I have access to the seeds, I don’t want to install it, and I don’t have access to the Leopard Dev Center.
June 26th, 2007 at 12:32 pm
I have a feeling that it works with the new Leopard APIs just fine (aside from having to cast that malloc to make GCC happy).
November 26th, 2007 at 12:32 pm
Thanks for this. I’ve made a stab at updating it for the Leopard runtime API; for the moment it’s just on the Cocoadev page on MethodSwizzling.