5

In Objective-C, you can change an object's dynamic type at runtime by assigning to it's isa member variable:

id object = ...;
object->isa = [SomeClass class];

Is this undefined behavior? I'm currently doing this as a kludge for something else, and it appears to be working, but I feel so dirty doing it this way. The new class I'm setting doesn't add any member variables, it just overrides one method and adds a new one, so the class size is the same. I feel like if I changed the object size, much badness would result.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • possible duplicate of [Objective-C: How to change the class of an object at runtime?](http://stackoverflow.com/questions/8512793/objective-c-how-to-change-the-class-of-an-object-at-runtime) – Gabriele Petronella Aug 28 '13 at 15:34
  • You can run into to problems with KVO. They use isa-swizzling too. Mike Ash has a complete solution however: http://www.mikeash.com/pyblog/friday-qa-2010-11-19-creating-classes-at-runtime-for-fun-and-profit.html – nielsbot Aug 28 '13 at 15:42

4 Answers4

1

The Objective-C runtime now provides a function to do this: object_setClass. The documentation doesn't say what restrictions there are, but (as others have stated) I imagine you would want to restrict the new class to a class with exactly the instance variable layout as the original class.

benzado
  • 82,288
  • 22
  • 110
  • 138
1

I think this is, as you say, dirty.

I suspect it will work if:

  • The newly assigned class is a subclass of the real class.
  • The new class doesn't add any member variables.

But I'll admit I don't know the nuts-and-bolts implementation of your Objective-C runtime system. I just know what makes sense to me for an implementation.

Darron
  • 21,309
  • 5
  • 49
  • 53
0

It's really bad form to change these, and it makes all sorts of assumptions about runtime behaviour -- you're much better off using the runtime functions although they don't provide you with a mechanism to directly change the class.

olliej
  • 35,755
  • 9
  • 58
  • 55
0

This answer by Joshua Weinberg provides the right way to do this. It worked for me. :)

And Darron was right with his educated guess :) it will only work if it's a superclass of the current object, and if you don't add any members.

Community
  • 1
  • 1
Alex Zak
  • 1,924
  • 2
  • 18
  • 26