“可变参数函数指的是可以接受任意多个参数的函数,我们最熟悉的可能就是 NSString 的 -stringWithFormat: 方法了”
摘录来自: 王巍 (onevcat). “Swifter - Swift 必备 Tips (第三版)”。 iBooks.
忍不住去了解一下这种函数, 满足一下自己的好奇心!
首先如果自己想实现这样一下函数, 需要了解3个C语言宏定义
stdarg.h 头文件定义了一个变量类型 va_list 和三个宏,这三个宏可用于在参数个数未知(即参数个数可变)时获取函数中的参数。
void va_start(va_list ap, last_arg) : 这个宏初始化 ap 变量,它与 va_arg 和 va_end 宏是一起使用的。last_arg 是最后一个传递给函数的已知的固定参数,即省略号之前的参数。
va_arg(va_list ap, type)这个宏检索函数参数列表中类型为 type 的下一个参数。
void va_end(va_list ap)这个宏允许使用了 va_start 宏的带有可变参数的函数返回。如果在从函数返回之前没有调用 va_end,则结果为未定义。
好了, 技术储备已经完成, 接下来上代码
- (NSArray *)actionUsePic:(id)actionNum, ... {
NSMutableArray *argsArray = [[NSMutableArray alloc] init];
va_list params; //定义一个指向个数可变的参数列表指针;
va_start(params,actionNum);//va_start 得到第一个可变参数地址,
id arg;
if (actionNum) {
//将第一个参数添加到array
id prev = actionNum;
[argsArray addObject:prev];
//va_arg 指向下一个参数地址
//这里是问题的所在 网上的例子,没有保存第一个参数地址,后边循环,指针将不会在指向第一个参数
while( (arg = va_arg(params,id)) )
{
if ( arg ){
[argsArray addObject:arg];
}
}
//置空
va_end(params);
//这里循环 将看到所有参数
for (NSNumber *num in argsArray) {
NSLog(@"%d", [num intValue]);
}
}
return argsArray;
}
值得注意的是, 参数的最后一个, 要写成nil, 方便 arg成功end, 释放var_list的内存.
下面是swift版的
“func sum(input: Int...) -> Int {
//...
return input.reduce(0, +)
}”
swift版超级简化有没有, 只需要加上... 哈哈哈