可变参数的方法在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. button上传替换file上传按钮,并显示图片缩略图,纯jsp操作

    1.jsp代码 <div class="inputBox"> <span id="tu" <c:if test="${pd = ...

  2. python -- numpy 基本数据类型,算术运算,组合,分割 函数

    0 NumPy数组 NumPy数组:NumPy数组是一个多维数组对象,称为ndarray.其由两部分组成: 实际的数据 描述这些数据的元数据 NumPy数组属性: ndim(纬数,x,y 2),sha ...

  3. maven jar包上传到服务器

    maven jar包上传到服务器时出现pom文件没有上传上去,致使该jar包再被使用的时候没有依赖,jar包调用出错 解决办法,将pom文件一起deploy上去 mvn deploy:deploy-f ...

  4. Linxu

    http://www.92csz.com/study/linux/ MySql 乱码  修改 /etc/my.cnf文件 character-set-server=utf8 , 表名不区分大小写:lo ...

  5. Android——shape和selector和layer-list的(详细说明 转)

    <shape>和<selector>在Android UI设计中经常用到.比如我们要自定义一个圆角Button,点击Button有些效果的变化,就要用到<shape> ...

  6. Android——线程通讯类Handler(转)

    原文地址:http://uule.iteye.com/blog/1705951 handler是线程通讯工具类.用于传递消息.它有两个队列:1.消息队列2.线程队列 消息队列使用sendMessage ...

  7. 使用livereload实现自动刷新

    livereload是一个web开发辅助工具,当我们修改完html.css和js的时候会自动刷新浏览器,解放码农的双手.这样在双屏切图.写js代码的时候会提高很多效率.livereload有很多版本, ...

  8. drupal pathauto的配置

  9. Android progressbar条形带背景渐变进度风格进度条

    效果图: 代码如下: <ProgressBar android:id="@+id/progressBar" style="?android:attr/progres ...

  10. Python 文件操作二

    readlines就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素 #coding=utf-8 f = ...