Cocoa predicateWithFormat vs stringWithFormat:前者应该和后者做同样的事情吗?

Cocoa predicateWithFormat vs stringWithFormat:前者应该和后者做同样的事情吗?,cocoa,macos,nsarray,nspredicate,Cocoa,Macos,Nsarray,Nspredicate,我有一个带有文件名的数组,当traceNum为1时,我想查找以例如00001.trc结尾的所有名称。我试过这个: NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum]; NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.t

我有一个带有文件名的数组,当
traceNum
为1时,我想查找以例如00001.trc结尾的所有名称。我试过这个:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum];
NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.trc%@", @"\"", traceNum, @"\""];
NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum]];
我的谓词是
SELF-ENDSWITH“%05d.trc”
,而不是
SELF-ENDSWITH“00001.trc”

我试过这个:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum];
NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.trc%@", @"\"", traceNum, @"\""];
NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum]];
我遇到了一个异常:
无法解析格式字符串“SELF-ENDSWITH%@%05d.trc%@”

所以我试了一下:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum];
NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.trc%@", @"\"", traceNum, @"\""];
NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum]];
它是有效的


那么除了
predicateWithFormat
之外,我真的需要
stringWithFormat
,还是在创建谓词的过程中我没有做正确的事情?

你是对的
predicateWithFormat:
stringWithFormat:
不同

它的不同有两个主要原因:

  • 它实际上并没有创建一个新字符串。它只是浏览格式字符串,看看下一个要替换的是什么,从
    va_列表中弹出该字符串,并将其装箱到相应的
    NSExpression
    对象中
  • 它必须支持
    NSString
    不支持的格式说明符:
    %K
    。这就是在关键路径中替换的方式。如果您试图使用
    %@
    替换属性名称,它实际上将被解释为文字字符串,而不是属性名称
  • 不支持使用像
    %05d
    中的
    05
    这样的格式约束(我不确定正确的术语是什么)。首先,这毫无意义
    NSPredicate
    进行数值比较(在这种情况下,
    00005
    5
    相同,因此零填充是不相关的)和字符串比较(在这种情况下,您可以在将字符串提交给
    NSPredicate
    之前自己格式化字符串)。(它进行其他比较,如收集操作,但我现在跳过这些)
  • 那么,你怎么做你想做的事呢?最好的方法如下:

    NSString *trace = [NSString stringWithFormat:@"%05d.trc", traceNum];
    NSPredicate *p = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", trace];
    

    通过这种方式,您可以执行所有所需的格式设置,但仍然可以使用更正确的方法,将常量字符串作为谓词格式传递。

    感谢您的详细回答