【问题标题】:How can I dynamically create an instance of an class?如何动态创建类的实例?
【发布时间】:2009-05-26 20:24:31
【问题描述】:

例子:

我有 10 个视图控制器,它们都以相同的方式分配和初始化:

UIViewController *controller = [[MyViewController alloc] initWithNib];

(注意 -initWithNib 是 UIViewController 子类的自定义方法)

下一个视图控制器类是OtherViewController,以此类推。我想懒洋洋地加载视图控制器,就在我需要它们的时候。但要做到这一点,我需要某种“数组”来为给定索引提供相应的类,以便我可以初始化它。

我最终创建了一个带有大开关语句的方法,它只会为每个视图控制器分别进行讨厌的分配和初始化。我对此不满意。如果我可以将适当的类分配给一个变量,然后在 switch 语句的末尾分配并从该变量初始化该类,那就更好了。

有没有办法做到这一点?

编辑:我找到了一个函数

id class_createInstance(Class cls, size_t extraBytes)

每个类似乎都有一个属性“类”。但我不能将它分配给实例变量。这不起作用:

Class cls = [UIImage class];
cls *image = [cls imageNamed:@"avatar.png"];

第一行编译。但是第二个给出了一个错误:“image undeclared”。

【问题讨论】:

  • 看起来与stackoverflow.com/questions/381793完全相同
  • 我已经编辑了我的答案以包含一个基本的工厂模式。你想做:id image = [cls imageNamed:@"avatar.png"]。但是,最好在此处使用通用的基本类型(即 UIImage* image = ...),因为您问题的第一部分表明情况就是这样。

标签: iphone objective-c cocoa-touch uikit


【解决方案1】:

如果您在编译时知道类的名称,则可以将类分配给 Class 变量。例如:

static Class factory[2];

factory[0] = [MyViewController1 class];
factory[1] = [MyViewController2 class];
...

然后你可以有(classid 将是一个在编译时已知的常量,它将映射到所需的类:

-(UIViewController*)createViewController:(int)classid
{
    return [[factory[classid] alloc] init];
}

假设该方法是在一个名为 MyFactory 的类中定义的,那么您可以这样做:

MyFactory * fac = [[MyFactory alloc] init];
UIViewController * v1 = [fac createViewController: 0]; // typed
id v2 = [fac createViewController: 1]; // untyped

如果您没有类的编译时名称,您可以简单地执行以下操作:

#include <objc/objc-runtime.h>

id object = [[NSClassFromString(@"TheClassName") alloc] init];

由于您最初的问题涉及一组 UIViewController,因此没有理由使用后一种方法失去类型安全性。

【讨论】:

    【解决方案2】:

    你想使用反射:

     id controller = class_createInstance(NSClassFromString(@"your class name"), 0/*extra bytes*/);
    

    Objective-C Runtime Reference

    【讨论】:

    • 我收到警告:“函数 'class_createInstance' 的隐式声明”
    • #import
    • @arul,可以做 [[NSClassFromString(@"MyClass") alloc] init] 吗?
    【解决方案3】:

    我上个月在博客上写过这个: http://igotosoft.blogspot.com/2009/05/dynamically-creating-viewscontrollers.html 本质上,它涉及一个我称为 ClassConstructor 的新类,它采用类名、init 方法名和逗号分隔的参数。当您需要创建该类的实例时,只需使用您的 [myClassConstructor create];

    【讨论】:

      【解决方案4】:

      你想要的是反射。虽然没有objective-c的概念 - 但该术语可能会帮助您更好地搜索您的答案。

      【讨论】:

      • -1???让我休息一下 - 这是一个完全正确的答案,也是一个小时后最初的唯一答案。仅仅因为您不知道特定语言并不意味着答案不正确 - 它很可能帮助其他用户回答问题。这个网站上的一些人需要不那么认真地对待自己,或者找到一个新的爱好。
      • 总有人会否决他们认为出于任何原因不合适的任何答案。赞成票比反对票付出的代价要多得多。只是不要让它打扰你,它对血压有害。
      【解决方案5】:

      Objective C Reference 也是查看调用的好地方。由于无法添加链接,请尝试搜索 Objective-C 2.0 运行时参考

      【讨论】:

        猜你喜欢
        • 2015-12-17
        • 2020-05-11
        • 1970-01-01
        • 1970-01-01
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多