首先:这是一个问题,抱歉,但我希望有人可以帮助我!
我正在iPhone上制作UIML渲染器。 UIML是一种描述接口的语言。 我想渲染XML并在iPhone上显示界面。
告诉你更好,我先解释一下我在做什么:
<?xml version="1.0"?>
<uiml>
<interface>
<structure>
<part id="hoofdView" class="ViewController">
<part id="viewVoorHoofdview" class="View">
<part id="label1" class="Label"/>
</part>
</part>
</structure>
<style>
<property part-name="label1" name="text">Dit is een label</property>
<property part-name="label1" name="position">50,50,100,150</property>
</style>
</interface>
<peers>
<presentation base="cocoa.uiml"/>
</peers>
</uiml>
这是一个UIML文档(界面)。这是一个简单的ViewController,带有View和带有文本“Dit is een label”的标签。 我正在做一些非常抽象的事情。
当我解析文档时,我发现class =“ViewController”
然后我们要研究词汇:
<d-class id="Label" used-in-tag="part" maps-type="class" maps-to="UILabel">
<d-property id="text" return-type="NSString*" maps-type="getMethod" maps-to="text"/>
<d-property id="text" maps-type="setMethod" maps-to="setText:">
<d-param type="NSString*"/>
</d-property>
<d-property id="position" maps-type="setMethod" maps-to="setFrame:">
<d-param type="CGRect"/>
</d-property>
</d-class>
为了方便你们,我只需粘贴一部分词汇。
在这个词汇表中,我们发现:
<d-class id="Label" used-in-tag="part" maps-type="class" maps-to="UILabel">
我在运行时正在制作UILabel:
NSObject * createdObject = [[NSClassFromString(className) alloc] init];
然后我必须将属性应用于createdObject。 我们有2个属性:文本和位置。
我们在词汇表中寻找它们(例如,让位置)
<d-property id="position" maps-type="setMethod" maps-to="setFrame:">
<d-param type="CGRect"/>
</d-property>
如您所见,我需要map-to和d-param来调用该方法。 但是有一个问题:在我们的第一份文件中:
<property part-name="label1" name="position">50,50,100,150</property>
首先,我必须将字符串50,50,100,150“解码”为CGRect,因为setFrame:需要一个CGRect作为参数。但是有一个大问题。我必须使这个非常抽象,但CGRect不是从NSObject继承的,因此我无法创建函数
-(NSObject*)convert:(NSString*)stringToConvert;
因为CGRect不是NSObject *。
当我必须传递一个浮点数(例如传递给UISlider)
时,会出现同样的问题<d-property id="minimumValue" maps-type="setMethod" maps-to="setMinimumValue:">
<d-param type="float"/>
</d-property>
我无法返回一个浮点数,因为NSObject不是它的超类。
我的转换方法如下所示:
-(NSObject *)convert:(NSString *)data parameterType:(NSString *)paramType {
NSObject * result;
if ( [paramType isEqualToString:@"NSString*"] ) {
result = data;
} else if ([paramType isEqualToString:@"float"]) {
//HOW TO DO THIS?
} else if ([paramType isEqualToString:@"CGRect"]) {
//HOW TO DO THIS?
} else {
NSLog(@"TypeDecoder: No decoding method found for the given parameter Type: %@", paramType);
}
return result;
}
我从中调用它的方法非常抽象,并且必须是抽象的,因为我们想要在不添加代码的情况下扩展UIML文档(词汇表)。 这是从以下方法调用它的方法:
-(void)invokeMethod:(Uproperty*)property dProperty:(DProperty *)dProperty guiElement:(NSObject *)object {
//Prepare the invocation
SEL selector = NSSelectorFromString(dProperty.m_mapsTo);
NSMethodSignature * signature = [ [object class] instanceMethodSignatureForSelector:selector];
NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:signature];
//target, selector, arguments
[invocation setTarget:object];
[invocation setSelector:selector];
//Convert the argument to the correct type with the type decoder
DParam *dParam = [dProperty.m_dParams lastObject];
NSObject * argument = [m_decoder convert:property.m_data parameterType:dParam.m_type]; //only 1 d-param
//Then we can set the argument
[invocation setArgument:&argument atIndex:2]; //2 is the first parameter (0 = self, 1 = _cmd)
//Invoke the method
[invocation invoke];
}
对于这个棘手的问题感到抱歉,但我希望有人可以帮助我!!
答案 0 :(得分:0)
您可能希望为不是NSObject的子类的所有类型构建包装类。 一个例子是NSNumber作为浮点数,整数等的对象包装器。