Как я могу получить тип входного аргумента селектора? - PullRequest
1 голос
/ 16 июля 2009

Я пытаюсь написать общий XML в парсер Core Data, используя libxml2. Поскольку у меня есть контроль над обоими, элементы XML точно соответствуют объектам, а атрибуты - свойствам объектов. Это все нормально и все работает хорошо, за исключением случаев, когда атрибуты имеют тип, отличный от NSString. Я понимаю, что селекторы ничего не знают о своих типах ввода, но есть ли другой способ определить их? То есть можно ли в общем случае преобразовать строку в тип, необходимый селектору, или мне нужно где-то написать переключатель if-then-else?

Вот мой текущий код:

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 < (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 && 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 && [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:&error])
    {
        if (parser.delegate != nil && [parser.delegate respondsToSelector:@selector(parser:didFailWithError:)]) {
            [parser.delegate parser:parser didFailWithError:error];
    }
    }
    [pool release];
}

1 Ответ

0 голосов
/ 16 июля 2009

Держал Google и обнаружил, что могу использовать NSMethodSignature:

- (const char *)getArgumentTypeAtIndex:(NSUInteger)index

Вот соответствующая документация .

Хотя там написано

Эта кодировка зависит от реализации, поэтому приложения должны использовать ее с осторожностью.

ETA: Ааа, я вернулся в тупик. Все, что я могу узнать, это то, что это класс. Я задам более конкретный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...