我遇到了问题:
我想使用变量的值来创建一个对象。
例如,我有一个变量myVar
。
If myVar == 'Client' : myVar* obj (obj will be an Client instance)
If myVar == 'People' : myVar* obj (obj will be an People instance)
有人可以帮帮我吗? (对不起我的英文)
答案 0 :(得分:6)
您可以使用NSClassFromString(@"ClassName")
从字符串中获取类。要获取课程的实例,请致电alloc
和init
。例如:
NSString *myString = [NSClassFromString(@"NSString") alloc] init];
如果您不确定要传递给NSClassFromString
的哪个班级,或者您想要传递不同的变量,可以使用类型id
,如下所示:< / p>
id myObject = [NSClassFromString(myVar) alloc] init];
如果希望Xcode支持该类的属性和方法的代码完成,则可能必须稍后对myObject
进行类型转换,或者将其重新分配给类型变量。
你可以read more about NSClassFromString in the developer documentation。
修改强>
由于此处还有一些关于运行时内省以及此代码的“脆弱”性质的讨论,我将再解释一下。 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:
。 (选择器的意思是“方法名称”,本质上是一个字符串。)假设我们在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!
}
更常见的是,您需要检查特定的行为而不是类,但尝试实例化Class
并检查它是否有效可能很有用。当您检查旧版iOS的向后兼容性时,这会有所帮助。
希望这有帮助!