可变参数的方法在Objective-C中不罕见,像Cocoa中的很多常见的方法都是可变参数的,如:
1 NSLog(NSString *format, ...) 2 + (id)arrayWithObjects:(id)firstObj, ... 3 + (id)dictionaryWithObjectsAndKeys:(id)firstObject , ...
那我们如何实现自己的变参方法呢,其实我们需要用到C语言中关于变参的一组宏:va_list,va_start,va_arg,va_end,以下示例是一个变参方法的实现:
main.m
1 #import <Foundation/Foundation.h> 2 #import "ChangeableParameterClass.h" 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 [ChangeableParameterClass method:@"测试可变参数" 6 withAuthorName:@"Kenmu" 7 withChangeableParameter:@"firstParameter", @"secondParameter", @"thirdParameter", @"fourthParameter", @"fifthParameter", nil]; 8 } 9 return 0; 10 }
ChangeableParameterClass.h
1 #import <Foundation/Foundation.h> 2 @interface ChangeableParameterClass : NSObject 3 /** 4 * 测试可变参数 5 * 6 * @param name 名称 7 * @param authorName 作者名称 8 * @param firstParameter 可变参数的第一个参数元素,“,...”表示可能存在后面的多个参数元素(可变参数必须是作为方法的最后一个参数,以“,...”方式结尾) 9 */ 10 + (void)method:(NSString *)name withAuthorName:(NSString *)authorName withChangeableParameter:(NSString *)firstParameter,...; 11 @end
ChangeableParameterClass.m
1 #import "ChangeableParameterClass.h" 2 @implementation ChangeableParameterClass 3 + (void)method:(NSString *)name withAuthorName:(NSString *)authorName withChangeableParameter:(NSString *)firstParameter,... { 4 NSLog(@"%@,作者:%@", name, authorName); 5 6 va_list list; //指向可变参数的指针list 7 va_start(list, firstParameter); //使用第一个参数来初使化指针list 8 NSLog(@"strCurrent=%@", firstParameter); //strCurrent=firstParameter 9 while (YES) { 10 NSString *strCurrent = va_arg(list, NSString *); 11 if (!strCurrent) { 12 break; 13 } 14 NSLog(@"strCurrent=%@", strCurrent); //strCurrent=secondParameter... 15 } 16 va_end(list); //结束可变参数的获取 17 } 18 @end
像大多数变参方法一样,未尾一定要加上nil,因为这一组宏都没有提供对参数个数的检测,当然你会问为何NSLog的参数中我们都不用在末尾添加nil的参数呢,那是因为NSLog的第一个参数是一个格式化字符串,通过这个字条串就能获得后面的参数个数,所以如果你的方法还能有其它的参数能够显式的指出变参个数,当然你也可以书写(但在方法体中需要修改为按已知个数调用va_arg),但是我仍然推荐以上的写法!
时间: 2024-10-27 08:14:10