Прежде всего: это вопрос, извините за это, но я надеюсь, что кто-то может мне помочь!C-structs, NSObjects, float, int, double,
Я делаю визуализатор UIML на iPhone. UIML - это язык для описания интерфейсов. Я хочу отобразить XML и показать интерфейс на iPhone.
Чтобы сообщить вам bettter, я сначала объяснить, что я делаю:
<?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 с представлением и меткой с текстом «Dit is een label». Я делаю что-то очень абстрактное.
Когда я разобрать документ, я считаю, класс = «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>
Как вы можете видеть, мне нужны карты-к и d-параметры для вызова метода. Но есть одна проблема: В первом документе мы имеем:
<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];
}
Извините за этот трудный вопрос, но я надеюсь, что кто-то может мне помочь !!
Есть ли даже конкретный вопрос? Потому что я этого не вижу. – Brendan