Update: This code was written pre-Leopard, and as such doesn’t run under ObjC 2. See JRSwizzle for an updated version that runs under Leopard and Snow Leopard.

Method 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.

6 Responses to “Method Swizzling reimplemented”
  1. Excellent idea. Hopefully the same idea can be implemented with the new API in Leopard as well.

  2. Kevin Ballard says:

    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.

  3. Emmanuel Goldstein says:

    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).

  4. 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.

  5. Thanks all for your contribution. I have updated the Leopard version gently provided by Aaron, because I found some problems with it. See the Cocoadev page http://www.cocoadev.com/index.pl?RecentChanges