Objective-C:如何在运行时更改对象的类?

标签 objective-c runtime uitableview protected

我试着回答 Using a UITableView subclass with a UITableViewControllerISA 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/

相关文章:

iphone - iOS:在pdf生成中绘制文本时如何设置字体?

objective-c - 将 UIColor 保存到 NSUserDefaults 并从中加载

data-structures - 什么是 Trie 数据结构的最佳/最差/平均情况 Big-O 运行时?

C运行时库: what for?

iphone - 如何更改 iphone 3.0 上 UITableViewCellStyleSubtitle 单元格的字体大小

ios - 如何使用 MKRoute 创建特定路径?

iOS,在 Objective C 中使用结构,结构值不可从 super View 分配

algorithm - 为什么插入排序的 O(n) nlogn 运行时间是最理想的?

ios - 从一个数据源切换到另一个数据源并重新加载 UITableView 时错位或隐藏 UITableView 部分标题

ios - Swift canEditRowAtIndexPath 在 UIPageViewController EZSwipeViewController 中不起作用