前言
在OC和Swift都是允許使用可變參數(shù)方法的,雖然可變參數(shù)方法在很大程度上違反了編碼規(guī)范,但是在一些特定場景卻又很好用。例如我們在OC中常用的方法NSLog以及Swift中使用的print。
在Swift中定義可變參數(shù)方法
class VariableArgumentsFunction: NSObject {
func variableArg1(args: Any...) -> Void {
print(args)
}
func variableArg2(first: Any, _ args: Any...) -> Void {
print(first)
print(args)
}
}
在Swift中定義可變參數(shù)方法很簡單,參數(shù)的類型后面加上... 就可以了。在使用時,調(diào)用方傳值的可變參數(shù)會以數(shù)據(jù)的形式存放在args中。
在OC中定義可變參數(shù)方法
+ (void)variableArg:(id)arg,... NS_REQUIRES_NIL_TERMINATION {
va_list args;
va_start(args, arg);
NSLog(@"%@", arg);
while (1) {
id arg = va_arg(args, id);
if (arg == nil) {
break;
}
NSLog(@"%@", arg);
}
va_end(args);
}
+ (void)variableArg1:(id)arg1 arg2:(id)arg2, ... NS_REQUIRES_NIL_TERMINATION {
va_list args;
va_start(args, arg2);
NSLog(@"%@", arg1);
NSLog(@"%@", arg2);
while (1) {
id arg = va_arg(args, id);
if (arg == nil) {
break;
}
NSLog(@"%@", arg);
}
va_end(args);
}
在OC中定義可變參數(shù)方法會略顯復(fù)雜。
方法聲明時在參數(shù)后面加 , ... ,最好是為方法加上NS_REQUIRES_NIL_TERMINATION進行修飾,這個宏定義是提示調(diào)用者這個方法的參數(shù)需要以nil結(jié)尾。
方法體中需要使用va_list來獲取可變參數(shù)列表,關(guān)于va_list會在后面的內(nèi)容進行描述。
調(diào)用方法時需要注意:
- 可變參數(shù)的類型都需要與
, ...前面的這個參數(shù)的類型一致。 - 如果不以
nil結(jié)尾,在va_arg時會報錯。
關(guān)于va_list
VA_LIST 是在C語言中解決變參問題的一組宏,所在頭文件:#include <stdarg.h>,用于獲取不確定個數(shù)的參數(shù)。
在OC中va_list的定義如下:
typedef __darwin_va_list va_list;
其它幾個相關(guān)函數(shù)定義如下:
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
本篇文章不對這些函數(shù)進行深入的挖掘,只簡單的解釋這些函數(shù)的用法。
-
va_list用于承載可變參數(shù)列表。在方法體中使用va_list args;來讓args變量接收可變參數(shù)列表 -
va_start獲取可變參數(shù)列表的第一個參數(shù)的地址(ap為va_list,param為方法聲明中可變參數(shù)左邊的那一個參數(shù)。也就是上面第一個方法中定義的arg,第二個方法中的arg2) -
va_arg獲取可變參數(shù)的當(dāng)前參數(shù),返回指定類型并將指針指向下一參數(shù)(type為參數(shù)的數(shù)據(jù)類型) -
va_end清空va_list可變參數(shù)列表
在方法體中有幾點需要注意:
-
va_list中不包含可變參數(shù)左邊的那一個(上面第一個方法中定義的arg,第二個方法中的arg2),所以在使用的時候需要注意。 - 參數(shù)的類型需要在方法體中自行控制,編譯器不會對參數(shù)的類型進行嚴(yán)格檢查,所以使用的時候需要考慮做類型校驗,防止報錯。
- 使用完參數(shù)之后,記得調(diào)用
va_end,防止出現(xiàn)靈異情況。