iOS可变参数定义以及调用

简介:

什么是可变长参数?


可变长参数:顾名思义,就是函数的参数长度(数量)是可变的。比如C语言的printf系列的(格式化输入输出等)函数,都是参数可变的。下面是printf函数的声明:

int printf(const char *format, …);

可变参数函数声明方式都是类似的



如何实现?

ObjC中没有提供直接的变长参数方法,需要使用C标准库中得av_list方法,使用简单:

C语言可变参数通过三个宏(va_start、va_end、va_arg)和一个类型(va_list)实现的。
具体的参数含义为:

va_list : 定义一个指向个数可变的参数列表指针,存储参数的类型信息。

void va_start(va_list ap, paramN) :

参数:
ap: 可变参数列表地址
paramN: 确定的参数
功能:初始化可变参数列表(把函数在paramN之后的参数地址放到ap中)。

void va_end(va_list ap) :

功能: 关闭初始化列表(将ap置空)

type va_arg(va_list ap, type) :

功能: 返回下一个参数的值

使用示例

类似格式化输出的示例

1
2
3
4
5
6
7
8
9
- (void)aMethod:(NSString *)a, ... {
va_list ap;
va_start(ap, a);

NSString *str = [[NSString alloc] initWithFormat:a arguments:ap];
NSLog(@"%@", str);

va_end(ap);
}

调用这个方法以及输出的结果为:

[self aMethod:@"传入两个参数一个是整数: %d,另外一个是字符串: %@", 12, @"哈哈"];

结果:传入两个参数一个是整数: 12,另外一个是字符串: 哈哈

类似sql语句赋值的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (NSArray *)actionUseNum: (id)actionNum, ... {
NSMutableArray *argsArray = [[NSMutableArray alloc] init];
va_list params; //定义一个指向个数可变的参数列表指针
id arg;
if (actionNum) {
va_start(params, actionNum); //得到第一个可变参数地址
// 将第一个参数添加到array,要根据情况来使用下面两句把第一个参数加入array,有的情况不用加入。
// 例如第一个参数是sql语句,后面的参数是sql ? 用的变量,那就要删除下面的两句。
id prev = actionNum;
[argsArray addObject:prev];
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;
}

调用这个方法以及输出的结果为:

[self actionUseNum:[NSNumber numberWithInt:1],
                    [NSNumber numberWithInt:2],
                    [NSNumber numberWithInt:3],
                    [NSNumber numberWithInt:4], nil];
1
2
3
4
5
结果为:
2015-12-31 13:06:29.214 ContactManagement[21213:713439] 1
2015-12-31 13:06:29.214 ContactManagement[21213:713439] 2
2015-12-31 13:06:29.214 ContactManagement[21213:713439] 3
2015-12-31 13:06:29.214 ContactManagement[21213:713439] 4
目录
相关文章
|
11月前
|
iOS开发
iOS URL参数转字典
iOS URL参数转字典
130 0
|
11月前
|
JSON 移动开发 数据格式
iOS url传递JSON格式参数方法
iOS url传递JSON格式参数方法
218 0
|
iOS开发
iOS开发 - 系统导航栏左右上角按钮如何不需要定义就可以添加小红点
iOS开发 - 系统导航栏左右上角按钮如何不需要定义就可以添加小红点
139 0
|
iOS开发 Python
iOS小技能:lldb打印block参数签名
iOS逆向时经常会遇到参数为block类型,本文介绍一个lldb script,可快速打印出Objective-C方法中block参数的类型。
159 0
iOS小技能:lldb打印block参数签名
|
存储 iOS开发
iOS小技能: get 和post 布尔值参数处理、按照时间分页的数据重复的处理
1. get 和post 布尔值参数处理:如果后台Bool 参数没有同时支持【 0,1】 ;和【 true false】,get请求的时候就需要特殊处理。 2. 按照时间分页的数据重复的处理
145 0
iOS小技能: get 和post 布尔值参数处理、按照时间分页的数据重复的处理
|
JavaScript Android开发 iOS开发
html通过js调用ios或android代码
html通过js调用ios或android代码
89 0
|
JavaScript Android开发 iOS开发
html通过js调用ios或android代码
html通过js调用ios或android代码
|
Web App开发 JavaScript iOS开发
求助,主页面通过iframe访问ngnix中的子页面,子页面中利用调用js方法判断localstonge中是否有值,ios不可用,关闭阻止跨网站追踪,safari可用
紧急求助,主页面通过iframe访问ngnix中的子页面,子页面中利用调用js方法判断localstonge中是否有值,ios不可用,关闭阻止跨网站追踪,safari可用
|
算法 安全 JavaScript
IOS 某电商App签名算法解析(二) Frida RPC调用
IOS 某电商App签名算法解析(二) Frida RPC调用
IOS 某电商App签名算法解析(二) Frida RPC调用
|
JavaScript 安全 Android开发
Vue.js - 单页面 SPA ,IOS 端页面跳转后调用微信 JSSDK 时报错: "invalid signature" 解决方案
Vue.js - 单页面 SPA ,IOS 端页面跳转后调用微信 JSSDK 时报错: "invalid signature" 解决方案
414 0