我有个问题 :
我想使用一个变量的值来创建一个对象。
例如,我有一个变量myVar
。
If myVar == 'Client' : myVar* obj (obj will be an Client instance)
If myVar == 'People' : myVar* obj (obj will be an People instance)
有人可以帮助我吗?(对不起我的英语不好)
我有个问题 :
我想使用一个变量的值来创建一个对象。
例如,我有一个变量myVar
。
If myVar == 'Client' : myVar* obj (obj will be an Client instance)
If myVar == 'People' : myVar* obj (obj will be an People instance)
有人可以帮助我吗?(对不起我的英语不好)
您将使用NSClassFromString(@"ClassName")
从字符串中获取类。要获取该类的实例,您可以调用alloc
and 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 的向后兼容性时,这会有所帮助。
希望这可以帮助!