2

我有个问题 :

我想使用一个变量的值来创建一个对象。

例如,我有一个变量myVar

If myVar == 'Client' :  myVar* obj (obj will be an Client instance)
If myVar == 'People' :  myVar* obj (obj will be an People instance)

有人可以帮助我吗?(对不起我的英语不好)

4

1 回答 1

6

您将使用NSClassFromString(@"ClassName")从字符串中获取类。要获取该类的实例,您可以调用allocand init。例如:

NSString *myString = [NSClassFromString(@"NSString") alloc] init];

如果您不确定要传递给哪个类NSClassFromString,或者如果您想传递不同的变量,您可以使用 type id,如下所示:

id myObject = [NSClassFromString(myVar) alloc] init];

myObject如果您希望 Xcode 支持该类的属性和方法的代码完成,您可能需要稍后进行类型转换,或将其重新分配给类型化变量。

您可以在开发人员文档中阅读更多关于 NSClassFromString 的信息

编辑:

由于这里还有一些关于运行时自省和这段代码的“脆弱”性质的讨论,我将再解释一下。Objective-C 运行时支持各种巧妙的技巧,包括从字符串实例化类。当然,您必须确保您首先获得了您所期望的那种对象。

从 NSClassFromString 返回的类实例化对象后,首先要检查的是对象是否为nil. 如果是,则 NSClassFromString 和 alloc 之间或 alloc 和 init 之间出现了问题。我敢打赌你的字符串实际上不是一个现有的类。所以,一个稍微安全一点的方法是这样的:

id myObject = nil;   // Declare a myObject variable. Initialize to nil
Class class = NClassFromString(myVar);

if(!class) 
{ 
  // The class doesn't exist, we can't make the object
}
else 
{
   myObject = [[class alloc] init]; // You can also use [class new] if you're using a vanilla initializer

  if(!myObject) 
  {
     // myObject couldn't be created for some reason...
  }
  else
  {
    // You've got an instance of your class
  }
} 

不过,我想更进一步,因为运行时很棒。

您还可以检查给定对象是否可以执行某些方法。为此,请查看respondsToSelector:. (Selector 的意思是“方法名”,本质上是一个字符串。)假设我们在 myObject 中有一个有效的对象,我们可以检查 myObject 是否可以执行某些操作,例如show.

if([myObject respondsToSelector:@selector(show)])
{
   [myObject show]; // Safe to call `show` here
}
else
{
   // Not safe, do something else!
}

我已经通过show了,@selector因为它是一个有效的方法,定义在UIAlertView.h. 如果我们不确定选择器的存在怎么办?好吧,我们可以从一个字符串创建一个选择器,就像我们对类所做的那样。这是它的工作原理:

SEL selector = NSSelectorFromString(@"myCustomMethod");

if ([myObject respondsToSelector:selector])
{
  [myObject performSelector:selector];
}

我们创建选择器,检查对象是否实现了该方法,如果实现了,则有效地调用该方法。

当我说您应该检查是否返回了您期望的对象时,我忘了提到您还可以询问运行时对象的类是否等于给定的类。这是一个例子:

id myObject = [[NSClassFromString(@"UIView") alloc] init];

if([myObject isKindOfClass:[UIView class]])
{
  // We've got a UIView. Set a frame, install it in a hierarchy, or have a drink with it.
}
else
{
  // Mayday!
}

通常情况下,您会想要检查特定行为而不是类,但尝试实例化 aClass并检查它是否有效可能很有用。当您检查旧版本 iOS 的向后兼容性时,这会有所帮助。

希望这可以帮助!

于 2013-05-26T07:05:44.273 回答