標籤:
可變參數的方法在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),但是我仍然推薦以上的寫法!
Objective-C文法之可變參數