Objective-C: How to change the class of an object at runtime?
If your tableview class provides ANY storage this will break. I would not recommend the path you're going down. But the correct method would be to use object_setClass(tableView, [MyTableView class])
.
Please make sure this is really what you want.
Here is a small code-sample showing how this is a horrible idea.
#import <objc/runtime.h>
@interface BaseClass : NSObject
{
int a;
int b;
}
@end
@implementation BaseClass
@end
@interface PlainSubclass : BaseClass
@end
@implementation PlainSubclass
@end
@interface StorageSubclass : BaseClass
{
@public
int c;
}
@end
@implementation StorageSubclass
@end
int main(int argc, char *argv[])
{
BaseClass *base = [[BaseClass alloc] init];
int * random = (int*)malloc(sizeof(int));
NSLog(@"%@", base);
object_setClass(base, [PlainSubclass class]);
NSLog(@"%@", base);
object_setClass(base, [StorageSubclass class]);
NSLog(@"%@", base);
StorageSubclass *storage = (id)base;
storage->c = 0xDEADBEEF;
NSLog(@"%X == %X", storage->c, *random);
}
and the output
2011-12-14 16:52:54.886 Test[55081:707] <BaseClass: 0x100114140>
2011-12-14 16:52:54.889 Test[55081:707] <PlainSubclass: 0x100114140>
2011-12-14 16:52:54.890 Test[55081:707] <StorageSubclass: 0x100114140>
2011-12-14 16:52:54.890 Test[55081:707] DEADBEEF == DEADBEEF
As you can see the write to storage->c
wrote outside the memory allocated for the instance, and into the block I allocated for random. If that was another object, you just destroyed its isa
pointer.
The safe way is to create a new instance.
Swapping isa
is not safe - you have no idea what the memory layout of a class is or what it will be in the future. Even moving up the inheritance graph is really not safe because objects' initialization and destruction would not be performed correctly - leaving your object in a potentially invalid state (which could bring your whole program down).