Objective-C:如何在运行时更改对象的类? [英] Objective-C: How to change the class of an object at runtime?

查看:86
本文介绍了Objective-C:如何在运行时更改对象的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图回答将UITableView子类与UITableViewController一起使用像这样使用 ISA交换:

I tried to answer Using a UITableView subclass with a UITableViewController with ISA Switching like so:

self.tableView->isa = [MyTableView class];

但是,我得到了编译错误:Instance variable 'isa' is protected.

But, I get the compile error: Instance variable 'isa' is protected.

有没有办法解决这个问题?而且,如果是这样,这样做安全吗?

Is there a way to get around this? And, if so, is it safe to do?

我问是因为 @AmberStar对这个问题的回答似乎有点缺陷. (请参阅我的评论.)

I'm asking because @AmberStar's answer to that question seems slightly flawed. (See my comment.)

推荐答案

如果您的表视图类提供了任何存储空间,则该存储空间将中断.我不推荐您要走的路.但是正确的方法是使用object_setClass(tableView, [MyTableView class]).

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);
}

和输出

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的写操作写在为实例分配的内存之外,并写入我为随机分配的块中.如果那是另一个对象,则只需销毁其isa指针即可.

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.

这篇关于Objective-C:如何在运行时更改对象的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆