最近写了一个自定义的 ActionSheet, 参考系统的 UIActionSheet 的创建方式设计 API. 我们知道系统的 UIAlertView 是使用可变参数来接收最后一个参数的, 我一直也只是知道怎么用, 于是这次查资料了解了可变参数的实现原理.
cocoa的API里使用到可变参数的地方
|
|
首先我们来看看C语言中常用的哨兵参数的实现
###哨兵参数
上面我们注意到, 哨兵参数实际上就是指定一个结束参数, 当遇到这个参数时停止接收参数.
我们再来看看OC里的可变参数的实现
|
|
上面我们主要用到了以下几个函数:
va_list argumentList : 定义一个指向可变参数列表的指针argumentList.
va_start(argumentList, last_determine_param) : 使用argumentList指针指向函数参数列表中的第一个参数.
- 说明 : 可变参数之前必须有一个或多个确定参数, last_determine_param是位于可变参数之前的最后一个固定参数( … 之前的最后一个参数). 调用va_start()时last_determine_param被用作第二个参数传入.
- 函数参数列表中参数在内存中的顺序与函数声明时的顺序是一致的, 比如有一个可变参数函数的声明是: void va_test(char a, char b, char c, …), 则它的固定参数依次是a, b, c, last_determine_param为c, 因此就是 va_start(arg_ptr, c).
va_arg(argList, type) : 返回argumentList所指的当前可变参数, 返回类型为type, 并使指针argumentList指向可变参数列表中的下一个参数.
va_end(argList) : 必须调用va_end()确保堆栈的正确恢复.
上述宏的原型如下:
- void va_start(va_list argptr, last_parm);
- type va_arg(va_list argptr, type);
- void va_end(va_list argptr);
它们都包含在头文件stdarg.h.
下面是自定义ActionSheet中可变参数的实际使用方式
|
|
|
|
传送门
本文Demo:VariableArgument
自定义ActionSheet:SRActionSheet
Have Fun.