iOS可变参数方法定义

前言

在OC和Swift都是允许使用可变参数方法的,虽然可变参数方法在很大程度上违反了编码规范,但是在一些特定场景却又很好用。例如我们在OC中常用的方法NSLog以及Swift中使用的print

在Swift中定义可变参数方法

class VariableArgumentsFunction: NSObject {
    
    func variableArg1(args: Any...) -> Void {
        print(args)
    }
    
    func variableArg2(first: Any, _ args: Any...) -> Void {
        print(first)
        print(args)
    }
}

在Swift中定义可变参数方法很简单,参数的类型后面加上... 就可以了。在使用时,调用方传值的可变参数会以数据的形式存放在args中。

在OC中定义可变参数方法

+ (void)variableArg:(id)arg,... NS_REQUIRES_NIL_TERMINATION {
    va_list args;
    va_start(args, arg);
    
    NSLog(@"%@", arg);
    
    while (1) {
        id arg = va_arg(args, id);
        if (arg == nil) {
            break;
        }
        NSLog(@"%@", arg);
    }
    va_end(args);
}

+ (void)variableArg1:(id)arg1 arg2:(id)arg2, ... NS_REQUIRES_NIL_TERMINATION {
    va_list args;
    va_start(args, arg2);
    
    NSLog(@"%@", arg1);
    NSLog(@"%@", arg2);
    
    while (1) {
        id arg = va_arg(args, id);
        if (arg == nil) {
            break;
        }
        NSLog(@"%@", arg);
    }
    va_end(args);
}

在OC中定义可变参数方法会略显复杂。
方法声明时在参数后面加 , ... ,最好是为方法加上NS_REQUIRES_NIL_TERMINATION进行修饰,这个宏定义是提示调用者这个方法的参数需要以nil结尾。
方法体中需要使用va_list来获取可变参数列表,关于va_list会在后面的内容进行描述。
调用方法时需要注意:

  • 可变参数的类型都需要与 , ... 前面的这个参数的类型一致。
  • 如果不以nil结尾,在va_arg时会报错。

关于va_list

VA_LIST 是在C语言中解决变参问题的一组宏,所在头文件:#include <stdarg.h>,用于获取不确定个数的参数。

在OC中va_list的定义如下:

typedef __darwin_va_list va_list;

其它几个相关函数定义如下:

#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap)          __builtin_va_end(ap)
#define va_arg(ap, type)    __builtin_va_arg(ap, type)

本篇文章不对这些函数进行深入的挖掘,只简单的解释这些函数的用法。

  • va_list用于承载可变参数列表。在方法体中使用va_list args;来让args变量接收可变参数列表
  • va_start获取可变参数列表的第一个参数的地址(apva_listparam为方法声明中可变参数左边的那一个参数。也就是上面第一个方法中定义的arg,第二个方法中的arg2)
  • va_arg获取可变参数的当前参数,返回指定类型并将指针指向下一参数(type为参数的数据类型)
  • va_end清空va_list可变参数列表

在方法体中有几点需要注意:

  1. va_list中不包含可变参数左边的那一个(上面第一个方法中定义的arg,第二个方法中的arg2),所以在使用的时候需要注意。
  2. 参数的类型需要在方法体中自行控制,编译器不会对参数的类型进行严格检查,所以使用的时候需要考虑做类型校验,防止报错。
  3. 使用完参数之后,记得调用va_end,防止出现灵异情况。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348

推荐阅读更多精彩内容