C-Structs, NSObjects, float, int, double, - PullRequest
0 голосов
/ 21 февраля 2010

Прежде всего: это хотя вопрос, извините за это, но я надеюсь, что кто-то может мне помочь!

Я делаю рендеринг UIML на iPhone. 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];

Затем я должен применить свойства к созданному объекту. У нас есть 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>

Я не могу вернуть float, потому что NSObject не является его суперклассом.

Мой метод convert выглядит так:

-(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];
}

Извините за этот сложный вопрос, но я надеюсь, что кто-то может мне помочь !!

1 Ответ

0 голосов
/ 25 марта 2010

Возможно, вы захотите создать классы-оболочки для всех типов, которые не являются подклассами NSObject. Примером является NSNumber в качестве обёртки объекта для чисел с плавающей запятой, целых и т. Д.

...