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) :

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

使用示例

类似格式化输出的示例

123456789
- (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语句赋值的示例

12345678910111213141516171819202122
- (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];
12345
结果为:2015-12-31 13:06:29.214 ContactManagement[21213:713439] 12015-12-31 13:06:29.214 ContactManagement[21213:713439] 22015-12-31 13:06:29.214 ContactManagement[21213:713439] 32015-12-31 13:06:29.214 ContactManagement[21213:713439] 4
时间: 2024-10-31 05:38:16

iOS可变参数定义以及调用的相关文章

Python函数可变参数定义及其参数传递方式实例详解

  本文实例讲述了Python函数可变参数定义及其参数传递方式.分享给大家供大家参考.具体分析如下: python中 函数不定参数的定义形式如下: 1.func(*args) 传入的参数为以元组形式存在args中,如: ? 1 2 3 4 5 6 def func(*args): print args >>> func(1,2,3) (1, 2, 3) >>> func(*[1,2,3]) #这个方式可以直接将一个列表的所有元素当作不定参数 传入(1, 2, 3) 2.

C语言中的可变参数函数的浅析(以Arm 程序中的printf()函数实现为例) .

我们在C语言编程中会遇到一些参数个数可变的函数,一般人对它的实现不理解.例如Printf():   Printf()函数是C语言中非常常用的一个典型的变参数函数,它 的原型为: int printf( const char* format, ...); 它除了一个参数format固定外,后面的参数的个数和类型是不确定的,如下列三种调用方法: 1.    printf("%d\n", i); 2.    printf("%s\n", "Hello World

C/C++语言中可变参数的用法

我们在C语言编程中会遇到一些参数个数可变的函数,例如printf() 这个函数,它的定义是这样的:  int printf( const char* format, ...);  它除了有一个参数format固定以外,后面跟的参数的个数和类型是  可变的,例如我们可以有以下不同的调用方法:  printf("%d",i);  printf("%s",s);  printf("the number is %d ,string is:%s", i,

Python中函数的参数定义和可变参数用法实例分析

  本文实例讲述了Python中函数的参数定义和可变参数用法.分享给大家供大家参考.具体如下: 刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函数定义,我们都知道,下面的代码定义了一个函数funcA ? 1 2 def funcA(): pass 显然,函数funcA没有参数(同时啥也不干:D). 下面这个函数funcB就有两个参数了, ? 1

C语言利用va_list、va_start、va_end、va_arg宏定义可变参数的函数

在定义可变参数的函数之前,先来理解一下函数参数的传递原理: 1.函数参数是以栈这种数据结构来存取的,在函数参数列表中,从右至左依次入栈. 2.参数的内存存放格式:参数的内存地址存放在内存的堆栈段中,在执行函数的时候,从最后一个(最右边)参数开始入栈.因此栈底高地址,栈顶低地址,举个例子说明一下: void test(int a, float b, char c); 那么,在调用test函数的时候,实参char c先进栈,然后是float b,最后才是int a,因此在内存中变量的存放次序是c->

《企业级ios应用开发实战》一3.6 可变参数

3.6 可变参数 我们知道,C和C++语言支持可变参数的函数,例如我们常用的NSLog和printf函数.Objective-C作为C语言的超集,当然毫无例外地也支持可变参数.迄今为止,我们至少用过了一种使用可变参数的方法,即NSString的stringWithFormat:方法. C语言通过stdarg.h库支持可变参数,Objective-C 也不例外.在C语言中,如果你要使用可变参数,必须包含头文件stdarg.h,但在Cocoa中却不必,因为苹果已经在 NSObjC Runtime.h

C语言可变参数在宏定义中的应用

       在C语言的标准库中,printf.scanf.sscanf.sprintf.sscanf这些标准库的输入输出函数,参数都是可变的.在调试程序时,我们可能希望定义一个参数可变的输出函数来记录日志,那么用可变参数的宏是一个不错的选择. 在C99中规定宏也可以像函数一样带可变的参数,如: #define LOG(format, ...) fprintf(stdout, format, __VA_ARGS__) 其中,...表示可变参数列表,__VA_ARGS__在预处理中,会被实际的参数

C/C++宏定义的可变参数详细解析_C 语言

编写代码的过程中,经常会输出一些调试信息到屏幕上,一般会调用printf这类的函数.但是当调试解决之后,我们需要手工将这些地方删除或者注释掉.最近在看<Linux C编程一站式学习>这本书,就想到一个方法: 复制代码 代码如下: void myprintf(char* fmt, ...){}#ifdef DEBUG#define printf(fmt, args...) myprintf(fmt, ##args)#endif 调试阶段带着DEBUG调试,正式上线就可以把printf变成一个空函

JRuby中调用java带可变参数的方法

今天同事遇到的问题,用JRuby调用一个java方法,该方法使用了jdk1.5的可变参数.我一开始以为只要简单地将可变参数表示为数组即可,例如下面的两个java类: public class Echo{ public void echo(String name){ System.out.println(name); } } public class Test{ public void hello(String name,Echoargs){ System.out.println("hello,&