我试着回答 Using a UITableView subclass with a UITableViewController与 ISA Switching像这样:
self.tableView->isa = [MyTableView class];
但是,我收到编译错误:Instance variable 'isa' is protected.
有没有办法解决这个问题?而且,如果是这样,这样做安全吗?
我问是因为 @AmberStar's answer to that question似乎有点缺陷。 (请参阅我的评论。)
最佳答案
如果您的 tableview 类提供任何存储,这将中断。我不会推荐你走的路。但正确的方法是使用 object_setClass(tableView, [MyTableView class])
。
请确保这确实是您想要的。
这是一个小代码示例,展示了这是一个多么可怕的想法。
#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);
}
和输出
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
如您所见,对 storage->c
的写入是在为实例分配的内存之外写入的,并且写入了我为随机分配的 block 。如果那是另一个对象,您只需销毁它的 isa
指针。
关于Objective-C:如何在运行时更改对象的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8512793/