I'm trying to follow the (brilliant) instructions from here, but I have an instance of a class that I cannot modify by subclassing. Is there any way to override methods to an instance of the class only?
2 Answers
Beware. You are about to enter some fairly deep magic in ObjC, and the kinds of bugs you can generate are mind-bending. These are the last techniques you should use after everything else has failed, and you should do whatever you can to isolate this code. That said, ObjC is a highly dynamic language, and you can rewire most things.
First, to your specific question, you can change the class of an instance, which will achieve what you want. The rules are basically:
- The new class should be a subclass of the former class
- The new class must not add any ivars. Adding ivars in the subclass is one of the things that can lead to the above-mentioned mind-bending bugs.
You will get no warnings or errors if you do this wrong. You will just get bizarre crashes.
Given that, changing an object's class is actually very easy:
object->isa = [NewClass class];
Beyond that, you can change the implementation of a method for every instance of a class using method swizzling. I have some examples of this in Hijacking with method_exchangeImplementations(). Good luck using the debugger once you've done this, though.

- 286,113
- 34
- 456
- 610
-
Thanks for that. It's fascinating, but it has convinced me to stick to my strengths and avoid this at all costs. – Dan Rosenstark Jul 23 '10 at 20:05
-
Actually, doesn't look too bad, actually might work out fine in my case. – Dan Rosenstark Jul 23 '10 at 20:52
-
2Used carefully, it's actually very simple. Just do everything you can to make sure none of the rest of your program cares about it. This is part of how KVO is implemented. The first time you observe an object with KVO, its class gets switched to a magic KVO subclass that modifies all the accessors. It all works fine, and you don't even notice; but I'm sure debugging the KVO code *itself* is a entertaining at best. Same with your problem; just document it very well or you'll never remember what you were doing. – Rob Napier Jul 24 '10 at 00:57
-
1Okay, thanks again. It looks like my Use Case has just been set to `nil` so I can avoid this for the time being. – Dan Rosenstark Jul 24 '10 at 17:56
Actually, you can modify anything with subclassing. It is one of the more delicate things you can do, and you can look into method swizling instead (but method swizling will effect all members of the class), but in objective c, it's super easy to set the class of any object, so basically all you need to do is declare a subclass which doesn't declare any extra ivars, and only overrides the methods you need, (and you probably want to call the super implementation), and then change the class of an object at runtime through object_setClass (declared in ).

- 4,925
- 2
- 29
- 39