Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I get the input argument type of a selector?
    text
    copied!<p>I'm trying to write a generic XML to Core Data parser using libxml2. Since I have control over both, the XML elements correspond exactly to the objects and the attributes to the properties of the objects. This is all fine and everything works well, except when the attributes are of a type other than NSString. I realize that selectors know nothing of their input types, but is there some other way to determine them? That is, can I generically convert the string to the type needed by the selector, or do I need to write an if-then-else switch somewhere?</p> <p>Here's my in-progress code:</p> <pre><code>static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes) { //set up a local pool so we can release these objects NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; FormParser *parser = (FormParser *)ctx; NSString *elementName = [[NSString alloc] initWithUTF8String:(const char *)localname]; NSManagedObject *localObject = [parser.managedObjectContext insertNewObjectForEntityForName:elementName]; // according to http://www.xmlsoft.org/html/libxml-SAX2.html#xmlSAX2StartElementNs, // there are 5 parts to the attribute array: localname/prefix/URI/value/end int attribCounter; for (attribCounter = 0; attribCounter &lt; (nb_attributes * 5); attribCounter++) { NSString *attributeValue = nil; NSString *attributeName = [[NSString alloc] initWithUTF8String:(const char *)attributes[attribCounter]]; //let's skip over the prefix attribCounter++; //and the URI attribCounter++; //and get to the value attribCounter++; //increment after using counter so we can get the end value const char *valueStart = (const char *)attributes[attribCounter++]; const char *valueEnd = (const char *)attributes[attribCounter]; //if we have good values, init a value with if (valueStart &amp;&amp; valueEnd) { attributeValue = [[NSString alloc] initWithBytes:attributes[attribCounter-1] length:(strlen(valueStart) - strlen(valueEnd)) encoding:NSUTF8StringEncoding]; } SEL setAttribute = NSSelectorFromString([NSString stringWithFormat:@"set%@:", [attributeName capitalizedString]]); if (attributeValue &amp;&amp; [localObject respondsToSelector:setAttribute]) { //HERE'S WHERE I NEED TO CHECK TYPE AND CAST IF NEEDED [localObject setValue:attributeValue forKey:attributeName]; } } //set parser's current object SEL setCurrent = NSSelectorFromString([NSString stringWithFormat:@"setCurrent%@:", [elementName capitalizedString]]); if ([parser respondsToSelector:setCurrent]) { [parser performSelector:setCurrent withObject:localObject]; } //set parent SEL setParent = NSSelectorFromString(@"setParent"); if ([localObject respondsToSelector:setParent]) { SEL getParent = NSSelectorFromString([NSString stringWithFormat:@"getCurrent%@", [[parser getElementParent:elementName] capitalizedString]]); if ([parser respondsToSelector:getParent]) { [localObject performSelector:setParent withObject:[parser performSelector:getParent]]; } } NSError *error = nil; if (![parser.managedObjectContext save:&amp;error]) { if (parser.delegate != nil &amp;&amp; [parser.delegate respondsToSelector:@selector(parser:didFailWithError:)]) { [parser.delegate parser:parser didFailWithError:error]; } } [pool release]; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload