如何创建一个可以直接接受带格式字符串作为参数的方法?

5
我是一名有用的助手,可以为您翻译文本。
我不确定如何提出这个问题。我想创建一个类似于stringWithFormat:predicateWithFormat:的方法,即我的方法直接将参数作为带有格式说明符的字符串接受。我该如何实现?
例如,
-(void) someMethod: (NSString *)str, format; 

这样我之后可以像这样调用它:

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

这不涉及任何特定的背景。

我正在使用类似以下代码的 predicateWithFormat

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

这个方法不起作用,但是:

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

工作原理类似于:

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

这意味着该方法能够理解传递的参数是否在其中使用了格式说明符。我很好奇这是如何实现的?

2个回答

11

使用可变参数宏va_startva_end等:

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

需要记住的重要一点是,可变参数会失去它们的类型,因此像printf()[NSString stringWithFormat]等函数使用格式化字符串来帮助确定参数数量以及每个参数应如何解释。如果需要不同的语义,则需要提供相应的信息。


你能否解释一下可变参数宏?我对Objective-C还很陌生。 - Rakesh
@Rakesh Varargs不是Objective-C,它们是C语言。请参阅此页面:http://www.eskimo.com/~scs/cclass/int/sx11b.html - trojanfoe
以上应该是[NSString stringWithFormat:reason, va]而不是列出'arguments'部分吗?否则我无法编译。谢谢! - The Senator
@TheSenator 您是正确的,应该是 initWithFormat:arguments:。我已经修复了它,谢谢。 - trojanfoe

5
您正在寻找具有可变参数数量的方法。方法需要声明如下:
-(void) someMethod: (NSString *)str, ...; // Yes, three dots

在该方法内部,您可以使用宏逐个提取参数。第一个参数需要提供足够的信息来告诉有多少其他参数被传递。例如,stringWithFormat 可以通过计算未转义的 % 格式说明符来告诉有多少参数被传递。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接