基于
this
所以几个小时前我问了这个问题,我决定实现一个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并返回
-
否则,循环参数
-
如果格式有位置变量(
%i$@
)对于位置i,将arg添加到新arg数组中
-
否则,不要添加参数
-
获取新的arg数组,将其转换回
va_list
和呼叫
initWithFormat:arguments:
得到正确的字符串。
我的想法是,我会全力以赴
[NSString stringWithFormat:]
而是通过此方法调用。
对于许多人来说,这似乎是不必要的,但是单击参考的so问题(第一行)以查看为什么需要这样做的示例。
思想?思想?更好的实施?更好的解决方案?