有没有办法从像@"xxx =%@,yyy =%@"和NSArray对象这样的格式字符串创建一个新的NSString?
在NSSTring类中有许多方法,如:
- (id)initWithFormat:(NSString *)format arguments:(va_list)argList - (id)initWithFormat:(NSString *)format locale:(id)locale arguments:(va_list)argList + (id)stringWithFormat:(NSString *)format, ...
但是没有它们将NSArray作为参数,我找不到从NSArray创建va_list的方法......
实际上从NSArray创建一个va_list并不困难.请参阅Matt Gallagher 关于此主题的优秀文章.
这是一个NSString类别,可以执行您想要的操作:
@interface NSString (NSArrayFormatExtension) + (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments; @end @implementation NSString (NSArrayFormatExtension) + (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments { char *argList = (char *)malloc(sizeof(NSString *) * arguments.count); [arguments getObjects:(id *)argList]; NSString* result = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease]; free(argList); return result; } @end
然后:
NSString* s = [NSString stringWithFormat:@"xxx=%@, yyy=%@" array:@[@"XXX", @"YYY"]]; NSLog( @"%@", s );
不幸的是,对于64位,va_list格式已经改变,因此上面的代码不再有效.并且可能不应该被使用,因为它取决于明显可能改变的格式.鉴于没有真正强大的方法来创建va_list,更好的解决方案是简单地将参数数量限制为合理的最大值(比如10),然后使用前10个参数调用stringWithFormat,如下所示:
+ (id)stringWithFormat:(NSString *)format array:(NSArray*) arguments { if ( arguments.count > 10 ) { @throw [NSException exceptionWithName:NSRangeException reason:@"Maximum of 10 arguments allowed" userInfo:@{@"collection": arguments}]; } NSArray* a = [arguments arrayByAddingObjectsFromArray:@[@"X",@"X",@"X",@"X",@"X",@"X",@"X",@"X",@"X",@"X"]]; return [NSString stringWithFormat:format, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9] ]; }
基于此答案使用自动参考计数(ARC):https://stackoverflow.com/a/8217755/881197
NSString
使用以下方法添加类别:
+ (id)stringWithFormat:(NSString *)format array:(NSArray *)arguments { NSRange range = NSMakeRange(0, [arguments count]); NSMutableData *data = [NSMutableData dataWithLength:sizeof(id) * [arguments count]]; [arguments getObjects:(__unsafe_unretained id *)data.mutableBytes range:range]; NSString *result = [[NSString alloc] initWithFormat:format arguments:data.mutableBytes]; return result; }
我想到的一个解决方案是,我可以创建一个适用于固定大量参数的方法,例如:
+ (NSString *) stringWithFormat: (NSString *) format arguments: (NSArray *) arguments { return [NSString stringWithFormat: format , (arguments.count>0) ? [arguments objectAtIndex: 0]: nil, (arguments.count>1) ? [arguments objectAtIndex: 1]: nil, (arguments.count>2) ? [arguments objectAtIndex: 2]: nil, ... (arguments.count>20) ? [arguments objectAtIndex: 20]: nil]; }
我还可以添加一个检查,以查看格式字符串是否包含超过21'%'的字符,并在这种情况下抛出异常.