可变参数的方法在Objective-C中不罕见,像Cocoa中的很多常见的方法都是可变参数的,如:

 NSLog(NSString *format, ...)
+ (id)arrayWithObjects:(id)firstObj, ...
+ (id)dictionaryWithObjectsAndKeys:(id)firstObject , ...

那我们如何实现自己的变参方法呢,其实我们需要用到C语言中关于变参的一组宏:va_list,va_start,va_arg,va_end,以下示例是一个变参方法的实现:

main.m

 #import <Foundation/Foundation.h>
#import "ChangeableParameterClass.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
[ChangeableParameterClass method:@"测试可变参数"
withAuthorName:@"Kenmu"
withChangeableParameter:@"firstParameter", @"secondParameter", @"thirdParameter", @"fourthParameter", @"fifthParameter", nil];
}
return ;
}

ChangeableParameterClass.h

 #import <Foundation/Foundation.h>
@interface ChangeableParameterClass : NSObject
/**
* 测试可变参数
*
* @param name 名称
* @param authorName 作者名称
* @param firstParameter 可变参数的第一个参数元素,“,...”表示可能存在后面的多个参数元素(可变参数必须是作为方法的最后一个参数,以“,...”方式结尾)
*/
+ (void)method:(NSString *)name withAuthorName:(NSString *)authorName withChangeableParameter:(NSString *)firstParameter,...;
@end

ChangeableParameterClass.m

 #import "ChangeableParameterClass.h"
@implementation ChangeableParameterClass
+ (void)method:(NSString *)name withAuthorName:(NSString *)authorName withChangeableParameter:(NSString *)firstParameter,... {
NSLog(@"%@,作者:%@", name, authorName); va_list list; //指向可变参数的指针list
va_start(list, firstParameter); //使用第一个参数来初使化指针list
NSLog(@"strCurrent=%@", firstParameter); //strCurrent=firstParameter
while (YES) {
NSString *strCurrent = va_arg(list, NSString *);
if (!strCurrent) {
break;
}
NSLog(@"strCurrent=%@", strCurrent); //strCurrent=secondParameter...
}
va_end(list); //结束可变参数的获取
}
@end

像大多数变参方法一样,未尾一定要加上nil,因为这一组宏都没有提供对参数个数的检测,当然你会问为何NSLog的参数中我们都不用在末尾添加nil的参数呢,那是因为NSLog的第一个参数是一个格式化字符串,通过这个字条串就能获得后面的参数个数,所以如果你的方法还能有其它的参数能够显式的指出变参个数,当然你也可以书写(但在方法体中需要修改为按已知个数调用va_arg),但是我仍然推荐以上的写法!

Objective-C语法之可变参数的更多相关文章

  1. Java可变参数 & Python可变参数 & Scala可变参数

    Java 可变参数的特点: (1).只能出现在参数列表的最后: (2)....位于变量类型和变量名之间,前后有无空格都可以: (3).调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体 ...

  2. Python星号*与**用法分析 What does ** (double star/asterisk) and * (star/asterisk) do for parameters? 必选参数 默认参数 可变参数 关键字参数

    python中*号**的区别 - CSDN博客 https://blog.csdn.net/qq_26815677/article/details/78091452 定义可变参数和定义 list 或 ...

  3. python 必选参数、默认参数、可变参数和、关键字参数

    转自:https://www.liaoxuefeng.com/wiki/897692888725344/897693568201440 可变参数 在Python函数中,还可以定义可变参数.顾名思义,可 ...

  4. python可变参数类型 a,*args,**kwargs

    a - int *args --tuple **kwargs -- dict *args是非关键字参数,用于元组,**kw是关键字参数,用于字典 可变参数 在Python函数中,还可以定义可变参数.顾 ...

  5. PHP基础语法: echo,var_dump, 常用函数:随机数:拆分字符串:explode()、rand()、日期时间:time()、字符串转化为时间戳:strtotime()可变参数的函数:PHP里数组长度表示方法:count($attr[指数组]);字符串长度:strlen($a)

    PHP语言原理:先把代码显示在源代码中,再通过浏览器解析在网页上 a. 1.substr;  //用于输出字符串中,需要的某一部分 <?PHP $a="learn php"; ...

  6. Java基础语法04面向对象上-类-属性-方法-可变参数-重载-递归-对象数组

    类 面向对象是一种思想,一般指将事务的属性与方法抽出总结为模板(类/class),处理事务时通过类创建/new出对象由对象的功能/方法去完成所要计算处理的事情. 面向过程:POP:以过程,步骤为主,考 ...

  7. C#与Java对比学习:数据类型、集合类、栈与队列、迭达、可变参数、枚举

    数据类型: C#:String与StringBuilder Java:String与StringBuffer 第一个不习惯是string的第一个字母必须大写了. 第二个不习惯是int得写成Intege ...

  8. 可变参数宏__VA_ARGS__

    在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:#define pr_debug(fmt,arg...) \printk(KERN_DEBUG fmt,##arg) 用可变参数宏(v ...

  9. Java 可变参数列表

    1.可变参数列表的简单实现 当调用方法时,方法的参数个数或类型未知时,称其为可变参数列表.在以前的Java代码中,可以使用Object数组来实现这样的功能.因为,所有的类都是直接或间接继承于Objec ...

随机推荐

  1. 基于jquery结婚电子请柬特效素材

    分享基于jquery结婚电子请柬特效素材总共包含3个部分,第一部分是开着小轿车缓缓进入场景,第二部分是相册,第三部分是祝福墙.效果图如下: 在线预览   源码下载 实现的代码. html代码: < ...

  2. Springmvc 定时器的实现

    有时候会需要项目中,定时去执行一些东西,这个时候就需要用到定时器了.比较简单, 当你springmvc环境搭建成功的时候. 本文转载自:https://www.cnblogs.com/wqj-blog ...

  3. 【转】使用scipy进行层次聚类和k-means聚类

    scipy cluster库简介 scipy.cluster是scipy下的一个做聚类的package, 共包含了两类聚类方法: 1. 矢量量化(scipy.cluster.vq):支持vector ...

  4. WPF通过EventTrigger改变其他控件的值

    场景:点击TextBox后弹出Poppup 原理:使用EventTrigger后触发StoryBoard,通过StoryBoard改变其他控件的值. 参考代码: <Grid> <Gr ...

  5. Python对字典(directory)按key和value排序

    distance = {9149: 0, 9150: 26, 9151: 24, 9152: 24, 9153: 24, 9154: 27, 9155: 25, 9156: 30, 9158: 20, ...

  6. C语言 · 比较字符串

    算法训练 比较字符串   时间限制:1.0s   内存限制:512.0MB      编程实现两个字符串s1和s2的字典序比较.(保证每一个字符串不是另一个的前缀,且长度在100以内).若s1和s2相 ...

  7. c# 利用反射清除事件

    控件的事件清除,除了-=,就只能依靠反射来执行了. /// <summary> /// 清除一个对象的某个事件所挂钩的delegate /// </summary> /// & ...

  8. C# 不借助第三个变量实现两整数交换

    c#中实现两个int变量的数值互换,在借助第三个变量做临时载体的情况下,非常简单. ; ; int c ; c = a; a = b; b = c; 如果不借助第三方变量,有几种实现的方法: 1.异或 ...

  9. ajax 多个参数问题,如何既能表单序列化获取,又能加参数,加全部代码

      $.param({'address':address,'delivity':delivity,'payment':payment}) + '&' + $('#card_form').ser ...

  10. find & grep 命令 in linux(转)

    Linux下面工作,有些命令能够大大提高效率.本文就向大家介绍find.grep命令,他哥俩可以算是必会的linux命令,我几乎每天都要用到他们.本文结构如下: -exec,find命令对匹配的文件执 ...