在做项目中,经常会有拼接字符串的需求.
比如:
如何拼接字符串能,一般我们会经过这么一个过程:
- (void)viewDidLoad {
[super viewDidLoad];
//显示: 申请秒豆: ??
NSString *numStr = @"20";
NSString *tips;
//初级做法. 直接使用系统API
tips = [NSString stringWithFormat:@"剩余天数: %@",numStr];
//或
tips = [@"剩余天数: " stringByAppendingString:numStr];
//中级做法. 使用宏来简化
#define AddStr(str1,str2) [str1 stringByAppendingString:str2]
tips = AddStr(@"剩余天数: ", numStr);
/*
但是遇到拼接两个以上字符串时,又变得麻烦了.
也许可以再定义一个宏,处理三个字符串的情况.
也可以像这样使用:
*/
tips = AddStr(@"活动", AddStr(@"剩余天数: ", numStr));
}
怎么样能够使拼接字符串变得更简单些呢?
下面直接上代码(我的Github):
最终结果:
tips = YCIJoinStrings(@"活动",@"剩余天数: ",numStr);
方案:
#import <Foundation/Foundation.h>
#define YCIJoinStrings(firstStr,...) [NSString JoinedWithSubStrings:firstStr,__VA_ARGS__,nil]
@interface NSString (YCI)
+ (NSString *)JoinedWithSubStrings:(NSString *)firstStr,...NS_REQUIRES_NIL_TERMINATION;
@end
#import "NSString+YCI.h"
@implementation NSString (YCI)
+ (NSString *)JoinedWithSubStrings:(NSString *)firstStr,...NS_REQUIRES_NIL_TERMINATION{
NSMutableArray *array = [NSMutableArray new];
va_list args;
if(firstStr){
[array addObject:firstStr];
va_start(args, firstStr);
id obj;
while ((obj = va_arg(args, NSString* ))) {
[array addObject:obj];
}
va_end(args);
}
return [array componentsJoinedByString:@""];
}
@end
注解:
考虑到要拼接的字符串个数不固定的因素,必须要使用va_list相关的方法
va_list
是在C语言中解决变参问题的一组宏.(具体参看:百度百科)
NS_REQUIRES_NIL_TERMINATION
因为使用va_list需要提前知道有多少个参数.这就增添了很大的不便.NS_REQUIRES_NIL_TERMINATION就是用于声明需要一个nil做结尾.就像我们使用NSArray的方法:
[NSArray arrayWithObjects:@"obj", nil];
通过在va_list的结尾插入一个nil,我们就可以用nil来做结尾的判断了.避免需要提前知道参数个数的麻烦.
可参考(曾迦的简书)
__VA_ARGS__
C99有了__VA_ARGS__的支持,我们可以进一步简化调用.