“可變參數(shù)函數(shù)指的是可以接受任意多個參數(shù)的函數(shù),我們最熟悉的可能就是 NSString 的 -stringWithFormat: 方法了”
? ? ? ? ?摘錄來自: 王巍 (onevcat). “Swifter - Swift 必備 Tips (第三版)”。 iBooks.
忍不住去了解一下這種函數(shù), 滿足一下自己的好奇心!
首先如果自己想實現(xiàn)這樣一下函數(shù), 需要了解3個C語言宏定義
stdarg.h?頭文件定義了一個變量類型?va_list?和三個宏,這三個宏可用于在參數(shù)個數(shù)未知(即參數(shù)個數(shù)可變)時獲取函數(shù)中的參數(shù)。
void va_start(va_list ap, last_arg)?:?這個宏初始化?ap?變量,它與?va_arg?和?va_end?宏是一起使用的。last_arg?是最后一個傳遞給函數(shù)的已知的固定參數(shù),即省略號之前的參數(shù)。
va_arg(va_list ap, type)這個宏檢索函數(shù)參數(shù)列表中類型為?type?的下一個參數(shù)。
void va_end(va_list ap)這個宏允許使用了?va_start?宏的帶有可變參數(shù)的函數(shù)返回。如果在從函數(shù)返回之前沒有調(diào)用?va_end,則結(jié)果為未定義。
好了, 技術(shù)儲備已經(jīng)完成, 接下來上代碼
- (NSArray?*)actionUsePic:(id)actionNum,?...?{??
NSMutableArray?*argsArray?=?[[NSMutableArray?alloc]?init];??
va_list?params;?//定義一個指向個數(shù)可變的參數(shù)列表指針;??
va_start(params,actionNum);//va_start?得到第一個可變參數(shù)地址,??
id?arg;??
if?(actionNum)?{??
//將第一個參數(shù)添加到array??
id?prev?=?actionNum;??
[argsArray?addObject:prev];??
//va_arg?指向下一個參數(shù)地址??
//這里是問題的所在?網(wǎng)上的例子,沒有保存第一個參數(shù)地址,后邊循環(huán),指針將不會在指向第一個參數(shù)??
while(?(arg?=?va_arg(params,id))?)??
{??
if?(?arg?){??
[argsArray?addObject:arg];??
}??
}??
//置空??
va_end(params);??
//這里循環(huán)?將看到所有參數(shù)??
for?(NSNumber?*num?in?argsArray)?{??
NSLog(@"%d",?[num?intValue]);??
}??
}??
return?argsArray;??
} ?
值得注意的是, 參數(shù)的最后一個, 要寫成nil, 方便 arg成功end, 釋放var_list的內(nèi)存.
下面是swift版的
“func sum(input: Int...) -> Int {
? ? //...
????????return input.reduce(0, +)
}”
swift版超級簡化有沒有, 只需要加上... 哈哈哈