2010-02-21 9 views
0

Tout d'abord: c'est une question bien, désolé pour cela, mais j'espère que quelqu'un peut m'aider! Je fais un rendu UIML sur l'iPhone. UIML est un langage pour décrire les interfaces. Je veux rendre le XML et montrer l'interface sur l'iPhone.C-structs, NSObjects, float, int, double,

Pour vous informer bettter d'abord, je vous expliquer ce que je fais:

<?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> 

Ce document est UIML (une interface). C'est un simple ViewController avec une vue et une étiquette avec le texte "Dit is een label". Je fais quelque chose de très abstrait.

Quand je parse le document, je trouve class = « ViewController »

Ensuite, nous devons regarder dans le vocabulaire:

<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> 

Pour le rendre facile pour vous les gars, je colle tout simplement une partie du vocabulaire.

Dans ce vocabulaire, nous trouvons:

<d-class id="Label" used-in-tag="part" maps-type="class" maps-to="UILabel"> 

Et je fais à l'exécution d'un UILabel:

NSObject * createdObject = [[NSClassFromString(className) alloc] init]; 

Puis-je appliquer les propriétés à l'createdObject. Nous avons 2 propriétés: texte et position.

Nous les cherchons dans le vocabulaire (nous allons prendre la position par exemple)

<d-property id="position" maps-type="setMethod" maps-to="setFrame:"> 
       <d-param type="CGRect"/> 
      </d-property> 

Comme vous pouvez le voir, j'ai besoin des cartes-à-d et pour invoquer la param méthode. Mais il y a un problème: Dans le premier document que nous avons:

<property part-name="label1" name="position">50,50,100,150</property> 

D'abord, je dois « décoder » la chaîne 50,50,100,150 à un CGRect car setFrame: a besoin d'un CGRect comme paramètre. Mais il y a un gros problème. Je dois faire ce très abstrait, mais CGRect n'est pas hérité de NSObject, et je ne peux donc pas faire fonction

-(NSObject*)convert:(NSString*)stringToConvert; 

Parce que CGRect n'est pas un NSObject *.

Le même problème se produit lorsque je dois passer un flotteur (par exemple à un UISlider)

<d-property id="minimumValue" maps-type="setMethod" maps-to="setMinimumValue:"> 
      <d-param type="float"/> 
     </d-property> 

Je ne peux pas retourner un flotteur parce NSObject n'est pas sa superclasse.

Mon converti méthode ressemble à ceci:

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

Et la méthode où je vous appelle cela de est très abstraite, et doit être abstraite, parce que nous voulons étendre le document UIML (vocabulaire) sans ajouter de code.Ce est la méthode où cela est appelé à partir:

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

Désolé pour cette question difficile, mais j'espère que quelqu'un peut me aider !!

+0

Y a-t-il même une question spécifique? Parce que je ne le vois pas. – Brendan

Répondre

0

Vous pouvez créer des classes wrapper pour tous les types qui ne sont pas une sous-classe de NSObject. Un exemple est NSNumber comme un wrapper d'objet pour les flottants, ints, etc.