Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a method which accepts strings with format directly as argument?

I don't know exactly how to put this question. I want to create a method like stringWithFormat: or predicateWithFormat:, i.e. my method accepts argument directly as a string with format specifiers. How can I achieve this?

E.g.,

-(void) someMethod: (NSString *)str, format; 

So that I can later call it like:

[someObject someMethod:@"String with format %@",anotherString];

This is not in relation to any particular context.

I was working predicateWithFormat with a code similar to:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like myName"];

This didn't work, but:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like 'myName'"];

worked similar to:

NSString *str = @"myName";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",str];

So this means the method is able to understand if the argument given has format specifiers used inside them. I'm curious how can this be done?

like image 932
Rakesh Avatar asked Jul 04 '12 12:07

Rakesh


2 Answers

Use the varargs macros va_start, va_end, etc:

-(void) someMethod: (NSString *)fmt, ...
{
    va_list va;
    va_start(va, fmt);    
    NSString *string = [[NSString alloc] initWithFormat:fmt
                                              arguments:va];
    va_end(va);

    // Do thing with string
}

The important thing to remember is that vararg parameters lose their type so functions like printf() and [NSString stringWithFormat] use the format string to help determine how many arguments there are and how each should be interpreted. If you need a different semantic then you will need to provide this information some how.

like image 85
trojanfoe Avatar answered Oct 12 '22 08:10

trojanfoe


You are looking for methods with variable number of parameters. Methods need to be declared like this:

-(void) someMethod: (NSString *)str, ...; // Yes, three dots

Inside the method you use macros to extract parameters one by one. The first parameter needs to supply enough information to tell how many other parameters are passed. For example, stringWithFormat can tell how many parameters are passed by counting unescaped % format specifiers.

- (void) someMethod:NSString *)str, ... {
    va_list args;
    va_start(args, str);
    int some_count = /* figure out how many args there are */;
    for( int i = 0; i < some_count; i++ ) {
        value = va_arg(args, <some_type>); // You need to derive the type from the format as well
    }
    va_end(args);
}
like image 5
Sergey Kalinichenko Avatar answered Oct 12 '22 08:10

Sergey Kalinichenko