iOS可变参数方法定义

2021-10-13  本文已影响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会在后面的内容进行描述。
调用方法时需要注意:

关于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)

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

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

  1. va_list中不包含可变参数左边的那一个(上面第一个方法中定义的arg,第二个方法中的arg2),所以在使用的时候需要注意。
  2. 参数的类型需要在方法体中自行控制,编译器不会对参数的类型进行严格检查,所以使用的时候需要考虑做类型校验,防止报错。
  3. 使用完参数之后,记得调用va_end,防止出现灵异情况。
上一篇下一篇

猜你喜欢

热点阅读