基于几个小时前提出的这个SO 问题,我决定实现一个 swizzled 方法,该方法允许我将格式化NSString
为 arg 格式stringWithFormat
,并且在省略一个编号的 arg 引用 ( %1$@, %2$@
)时不会中断
我有它的工作,但这是第一个副本,并且看到这个方法可能会在每次应用程序运行时被调用数十万次,我需要从一些专家那里反弹,看看这个方法是否有任何危险信号, 主要性能影响或优化
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
@implementation NSString (UAFormatOmissions)
+ (id)uaStringWithFormat:(NSString *)format, ... {
if (format != nil) {
va_list args;
va_start(args, format);
// $@ is an ordered variable (%1$@, %2$@...)
if ([format rangeOfString:@"$@"].location == NSNotFound) {
//call apples method
NSString *s = [[[NSString alloc] initWithFormat:format arguments:args] autorelease];
va_end(args);
return s;
}
NSMutableArray *newArgs = [NSMutableArray arrayWithCapacity:NUMARGS(args)];
id arg = nil;
int i = 1;
while (arg = va_arg(args, id)) {
NSString *f = [NSString stringWithFormat:@"%%%d\$\@", i];
i++;
if ([format rangeOfString:f].location == NSNotFound) continue;
else [newArgs addObject:arg];
}
va_end(args);
char *newArgList = (char *)malloc(sizeof(id) * [newArgs count]);
[newArgs getObjects:(id *)newArgList];
NSString* result = [[[NSString alloc] initWithFormat:format arguments:newArgList] autorelease];
free(newArgList);
return result;
}
return nil;
}
基本算法是:
%1$@
通过搜索来搜索,%2$@
变量的格式字符串%@
- 如果没有找到,调用正常的 stringWithFormat 并返回
- 否则,遍历 args
- 如果格式具有
%i$@
位置 i 的位置变量 ( ),则将 arg 添加到新的 arg 数组 - 否则,不要添加 arg
- 获取新的 arg 数组,将其转换回 a
va_list
,然后调用initWithFormat:arguments:
以获取正确的字符串。
这个想法是我将[NSString stringWithFormat:]
通过此方法运行所有调用。
这对许多人来说似乎是不必要的,但请单击引用的 SO 问题(第一行)以查看我为什么需要这样做的示例。
想法?想法?更好的实现?更好的解决方案?