簡介
一個可變引數函式是指一個函式擁有不定的引數,即為一個函式可接收多個引數。有時我們會遇到一些算術問題需要用到,比如是計算傳入引數的總和,字串的連線或是其它操作過程,我們在 OC 裡也經常使用,最經典的就是 NSLog( C 為 printf ) ,它可以指定格式的輸出,格式化輸出的內容。
舉個栗子?
新建一個類**TestClass
**,寫一個類方法print:
用於輸出我們傳入的值
類標頭檔案TestClass.h
#import <Foundation/Foundation.h>
@interface TestClass : NSObject
+ (void)print:(NSString *)firstArg, ... NS_REQUIRES_NIL_TERMINATION;
@end
複製程式碼
類實現TestClass.m
#import "TestClass.h"
@implementation TestClass
+ (void)print:(NSString *)firstArg, ... NS_REQUIRES_NIL_TERMINATION {
if (firstArg) {
// 取出第一個引數
NSLog(@"%@", firstArg);
// 定義一個指向個數可變的引數列表指標;
va_list args;
// 用於存放取出的引數
NSString *arg;
// 初始化變數剛定義的va_list變數,這個巨集的第二個引數是第一個可變引數的前一個引數,是一個固定的引數
va_start(args, firstArg);
// 遍歷全部引數 va_arg返回可變的引數(a_arg的第二個引數是你要返回的引數的型別)
while ((arg = va_arg(args, NSString *))) {
NSLog(@"%@", arg);
}
// 清空引數列表,並置引數指標args無效
va_end(args);
}
}
@end
複製程式碼
va_list:用來儲存巨集 va_start 、va_arg 和 va_end 所需資訊的一種型別。為了訪問變長引數列表中的引數,必須宣告 va_list 型別的一個物件。
va_start:訪問變長引數列表中的引數之前使用的巨集,它初始化用va_list宣告的物件,初始化結果供巨集va_arg和va_end使用;
va_arg:展開成一個表示式的巨集,該表示式具有變長引數列表中下一個引數的值和型別。每次呼叫 va_arg 都會修改,用 va_list 宣告的物件從而使該物件指向引數列表中的下一個引數。
va_end:該巨集使程式能夠從變長引數列表用巨集 va_start 引用的函式中正常返回。
NS_REQUIRES_NIL_TERMINATION :是一個巨集,用於編譯時非nil結尾的檢查。
試一試
在外部呼叫一個剛剛寫的方法
注意:
- 在可變引數裡,所有引數均用逗號隔開
- 引數結尾必須加上nil,表示引數結束
#import <Foundation/Foundation.h>
#import "TestClass.h"
int main(int argc, const char * argv[]) {
[TestClass print:@"a", @"b", @"c", nil];
return 0;
}
複製程式碼
看一下執行的結果,輸出了我們預期的值