简介
一个可变参数函数是指一个函数拥有不定的参数,即为一个函数可接收多个参数。有时我们会遇到一些算术问题需要用到,比如是计算传入参数的总和,字符串的连接或是其它操作过程,我们在 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;
}
看一下执行的结果,输出了我们预期的值