【问题标题】:predicateWithFormat vs stringWithFormat: is the former supposed to do the same as the latter?predicateWithFormat vs stringWithFormat:前者应该和后者一样吗?
【发布时间】:2011-08-30 04:17:37
【问题描述】:

我有一个包含文件名的数组,我想找到所有以 e.g. 结尾的名称。 00001.trctraceNum 为 1 时。我试过这个:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum];

我的谓词是SELF ENDSWITH "%05d.trc" 而不是SELF ENDSWITH "00001.trc"

我试过了:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.trc%@", @"\"", traceNum, @"\""];

我遇到了一个例外:Unable to parse the format string "SELF ENDSWITH %@%05d.trc%@"

所以我尝试了这个:

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

它有效。

那么除了predicateWithFormat 之外,我真的还需要stringWithFormat,还是我在创建谓词时做的不对?

【问题讨论】:

    标签: cocoa macos nsarray nspredicate


    【解决方案1】:

    你是对的; predicateWithFormat:stringWithFormat: 不太一样。

    之所以不同,主要有以下几个原因:

    1. 实际上并没有创建一个新字符串。它只是查看格式字符串并查看下一个要替换的内容,将其从 va_list 中弹出,并将其装箱到适当的 NSExpression 对象中。
    2. 它必须支持NSString 不支持的格式说明符:%K。这就是您在关键路径中进行替换的方式。如果您尝试使用 %@ 替换属性名称,它实际上会被解释为文字字符串,而不是属性名称。
    3. 不支持像%05d 中的05 那样使用格式约束(我不确定正确的术语是什么)。一方面,这没有意义。 NSPredicate 进行数值比较(在这种情况下,000055 相同,因此零填充无关紧要)和字符串比较(您可以在将字符串提供给 NSPredicate 之前自行格式化字符串)。 (它会进行其他比较,例如收集操作,但我现在跳过这些)

    那么,你如何做你想做的事?最好的方法是这样的:

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

    这样你可以做你想要的所有格式,但仍然使用传递常量字符串作为谓词格式的更正确的方法。

    【讨论】:

    • 感谢您的详尽回答
    猜你喜欢
    • 2018-12-13
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多