Obejctive-C 中定义可变参函数
為什么80%的碼農都做不了架構師?>>> ??
Objective-C?中有許多不定參數函數,像 NSLog(format, arg1, arg2),還有字符串或數組在構造時所用的 [NSString stringWithFormat: format, arg1, arg2, arg3],它們的方法原型分別是:
FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
+ (id)stringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
應該去掉后面的?NS_FORMAT_FUNCTION(1,2)?來看,否來會干擾到思維。我們現在的例子還不需要這么寫,至于?NS_FORMAT_FUNCTION(1,2)?的功用為何,我有時間還得好生看下。OK, 看多了?Apple?的那些可變參函數,可能反而令你感到費解,還不如來試個實際的例子:
- (void)foo:(NSString *)format, ... {va_list args;va_start(args, format);NSString *str = [[NSString alloc] initWithFormat:format arguments:args];va_end(args);printf([str UTF8String]);[str release]; } - (IBAction) doo: (UIButton*) sender {//須留意不定參函數的調用格式,逗號分隔的序列,應該它們整體是作為函數的一個參數傳入[self foo : @"My name %@, %@", @"Unmi", @"Yes"]; }上面的代碼我未加注釋,演示的是點擊界面某個按鈕來觸發執行的,調用 NSString?的?initWithFormat?把傳入的格式字符串及后面不定數量的參數拼接成一個字符串,然后打印出:
My name Unmi, Yes
到現了,已經有個體驗了,也看到 va_list,va_start,va_end?那幾個西正是處理不定參數的關鍵元件。下面要稍加深入去理解它們了。
現在重寫前面的?foo?方法:
- (void)foo:(NSString *) format, ... { NSString* eachArg;va_list argList;if (format) // 第一個參數 format 是不屬于參數列表的,{ va_start(argList, format); // 從 format 開始遍歷參數,不包括 format 本身.while (eachArg = va_arg(argList, NSString*)) // 從 args 中遍歷出參數,NSString* 指明類型NSLog(@"%@",eachArg); // 打印出每一個參數.va_end(argList);} }可以逐個打印出第一個之后的參數,如:
2011-06-17 02:05:28.840 Ohh[21874:40b] Unmi
2011-06-17 02:05:31.279 Ohh[21874:40b] Yes
每一個參數都能處理,那接下來自己寫更復雜的類似函數不會有什么問題了,不定參數可以指定任何實際的類型,(id) 可真是任何類型了。
跟?Java?的不定參函數一樣,不定的那些參數最終是作為函數的一個數組參數,Objective-C?的那堆參數也是變成函數的一個參數 args?參數列表。而且同樣的,Objective-C?的不定參數,即 ... 也必須放在函數的最后面,如還有其他參數時,foo?要寫成:
- (void)foo: state: (BOOL) enable withFormat: (NSString *)format, ...
而不能是:
- (void)foo: format: (NSString *)format, ... withState: (BOOL) enable
最后那幾個關鍵件要說明一下:
va_list argList:定義一個指向個數可變的參數列表指針;
va_start(argList,statement):使參數列表指針arg_ptr指向函數參數列表中的第一個可選參數,說明:argN是位于第一個可選參數之前的固定參數,(或者說,最后一個 固定參數;…之前的一個參數),函數參數列表中參數在內存中的順序與函數聲明時的順序是一致的。如果有一va函數的聲明是void va_test(char a, char b, char c, …),則它的固定參數依次是a,b,c,最后一個固定參數argN為c,因此就是va_start(arg_ptr, c)。
va_arg(argList,id):返回參數列表中指針arg_ptr所指的參數,返回類型為type,并使指針arg_ptr指向參數列表中下一個參數。
va_end(arg_ptr):清空參數列表,并置參數指針arg_ptr無效。
在調用的時候要在參數結尾的時候加 nil,回想下 [NSMutableArray arrayWithObjects: 1, 2, 3, nil]?這個構造過程,最后一個?nil?能讓 va_arg?取參數時碰到?nil?則斷定為?NO,終止循環。為何像?NSLog?調用不需要最后一個 nil?
參考:
1.?關于可變參數函數的定義
2.?Object c-可變參數函數的定義
轉載于:https://my.oschina.net/u/865478/blog/290516
總結
以上是生活随笔為你收集整理的Obejctive-C 中定义可变参函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL注入中load_file()函
- 下一篇: UIGestureRecognizer与