我正在使用Python编写一个脚本,该脚本从自定义文本中读取并从中生成Objective-C代码。文本结构如下:
<XClassName> {
property_name_1 {
var_name_1: var_value_1
var_name_2: var_value_2
property_name_2 {
var_name_3: var_value_3
}
property_name_2 {
var_name_3: var_value_4
}
}
property_name_3 {
}
}
导致像这样的Objective-C代码:
XClassName* object = [[XClassName alloc] init];
object.propertyName1 = [[[object.propertyName1 class] alloc] init];
object.propertyName1.varName1 = varValue1;
object.propertyName1.varName2 = varValue2;
object.propertyName2Array = [NSMutableArray array];
{
PropertyName2Class propertyName2 = [[PropertyName2Class alloc] init];
propertyName2.varName3 = varValue3;
[object.propertyName2Array addObject:propertyName2];
}
{
PropertyName2Class propertyName2 = [[PropertyName2Class alloc] init];
propertyName2.varName3 = varValue4;
[object.propertyName2Array addObject:propertyName2];
}
object.propertyName3 = [[[object.propertyName3 class] alloc] init];
这很好,只是在脚本运行时期间不知道PropertyName2Class
。现在我必须手动查找对象数组所期望的元素的类名,但是这会使脚本自动化它的目的。
有没有办法动态创建对象而不知道它的类名并为其属性赋值?类似的东西:
id classObject = ...; // How to instantiate a dynamic unknown class?
classObject.property1 = 1;
classObject.property2 = @"Hello World!";
有什么想法吗?
答案 0 :(得分:5)
如果您知道要实例化的类存在,例如,如果它作为变量传入,则相对容易。你可以这样做:
- (id)createInstanceOfClass: (NSString *)className
{
Class aClass = NSClassFromString(className);
id instance = nil
if(nil != aClass)
{
instance = [[aClass alloc] init];
}
return instance;
}
如果它还不存在,你可以在运行时间内创建它的一个实例,但这有点棘手(而且有点笨拙)。
<强>更新强>
我会避免尝试使用具有您已经存在的属性的类,除非您确定它的实现是什么。更安全的解决方案是从头开始构建一个类,并指定实现是什么。
尝试阅读:
http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html
(不适合胆小的人!)
另请参阅Objective-C运行时引用:
答案 1 :(得分:3)
我使用NSMutableDictionary:
NSMutableDictionary *object = [NSMutableDictionary dictionary];
[object setValue:[NSNumber numberWithInt:1] forKey:@"property1"];
[object setValue:@"Hello World!" forKey:@"property2"];
NSMutableDictionary *subObject = [NSMutableDictionary dictionary];
[subObject setValue:@"Hello sub!" forKey:@"property1"];
[object setValue:subObject forKey:@"property3"];