iOS 可变参数

一、可变参数是什么

想定义一个方法,但是不知道以后要用的时候想传几个参数进去,最经典的例子就是UIAlertView的构造方法
在 Objective-C 中:

- (instancetype)initWithTitle:(nullable NSString *)title message:(nullable NSString *)message delegate:(nullable id /**/)delegate cancelButtonTitle:(nullable NSString *)cancelButtonTitle otherButtonTitles:(nullable NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION

在 Swift 中:

public convenience init(title: String, message: String, delegate: UIAlertViewDelegate?, cancelButtonTitle: String?, otherButtonTitles firstButtonTitle: String, _ moreButtonTitles: String...)

下面我将分别用 Objective-C 和 Swift 实现。

二、Objective-C 实现可变参数

首先必须了解各个宏的功能是什么:

  1. NS_REQUIRES_NIL_TERMINATION:是一个宏,用于编译时非nil结尾的检查。 调用时要以nil结尾,否则会崩溃。
  2. va_list:用于声明一个变量,函数的可变参数列表其实就是一个字符串,所以va_list才被声明为字符型指针,这个类型用于声明一个指向参数列表的字符型指针变量,例如:va_list ap; //ap:arguement pointer
  3. va_start(ap,v):它的第一个参数是指向可变参数字符串的变量,第二个参数是可变参数函数的第一个参数,通常用于指定可变参数列表中参数的个数。
  4. va_arg(ap,t):它的第一个参数指向可变参数字符串的变量,第二个参数是可变参数的类型。
  5. va_end(ap):用于将存放可变参数字符串的变量清空(赋值为NULL)。
// .h文件中
- (NSString *)addMoreArguments:(NSString *)firstStr,...NS_REQUIRES_NIL_TERMINATION;

// .m文件中
- (NSString *)addMoreArguments:(NSString *)firstStr,...
{
    //定义一个指向个数可变的参数列表指针
    va_list args; 
    // 获取第一个可选参数的地址.使参数列表指针指向函数参数列表中的第一个可选参数
    va_start(args, firstStr);
    NSMutableString *allStr = [NSMutableString string];
    // 遍历参数,直到等于nil时结束
    for (NSString *str = firstStr; str != nil; str = va_arg(args, NSString *)) {
        [allStr appendFormat:@"%@",str];
    }
    // 清空参数列表,并置参数指针args无效
    va_end(args);
    return allStr;
}

三、Swift 实现可变参数

Swift 的实现比 Objective-C 简单太多太多

func addMoreArguments(firstStr: String...) {
      var result = String()
      // 遍历参数
      for str in firstStr {
          result += str
      }
      print(result)
}

这是用 Swift 实现与 Objective-C 完全相同功能的代码,哪个简单?不言而喻~~

你可能感兴趣的:(iOS 可变参数)