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

SSt*_*eve 3 macos cocoa nsarray nspredicate

我有一个带有文件名的数组,我想找到所有以00001.trc结尾的名称,当它traceNum是1.我试过这个:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum];
Run Code Online (Sandbox Code Playgroud)

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

我试过这个:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@%05d.trc%@", @"\"", traceNum, @"\""];
Run Code Online (Sandbox Code Playgroud)

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

所以我尝试了这个:

NSPredicate *tracePredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"SELF ENDSWITH \"%05d.trc\"", traceNum]];
Run Code Online (Sandbox Code Playgroud)

它的工作原理.

那么我真的需要stringWithFormat除了predicateWithFormat或者是否有一些我在创建谓词时没有正确做的事情?

Dav*_*ong 5

你是对的; predicateWithFormat:与...不完全相同stringWithFormat:.

由于几个主要原因,它有所不同:

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

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

NSString *trace = [NSString stringWithFormat:@"%05d.trc", traceNum];
NSPredicate *p = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", trace];
Run Code Online (Sandbox Code Playgroud)

这样,您就可以做所有你想要的格式,但仍使用传递一个常量字符串作谓语格式的更正确的做法.