美文网首页
iOS可变参数方法定义

iOS可变参数方法定义

作者: 一纸苍白 | 来源:发表于2021-10-13 15:47 被阅读0次

    前言

    在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,防止出现灵异情况。

    相关文章

      网友评论

          本文标题:iOS可变参数方法定义

          本文链接:https://www.haomeiwen.com/subject/uhfeoltx.html