Objective-C中編寫省略參數的多參函數

Objective-C中編寫省略參數的多參數函數

引語:

在Object-C中,咱們會遇到不少像NSLog這樣的函數,其中參數的個數不肯定,由程序員自由控制,在初始化數組,字典等方面應用普遍,那麼,這類的函數是如何實現的呢?咱們怎麼編寫咱們本身的省略參數的函數呢?固然,這不是惟一的多參函數的處理方法,你也能夠經過一個字典或者數組傳遞參數。但C爲咱們提供的這樣的一種機制,無疑是最方便的。程序員

1、瞭解幾個概念

va_list數組

C語言中定義的一個指針,用於指向當前的參數。函數

 

 

va_start(ap,param)spa

 

這個宏是初始化參數列表,其中第一個參數是va_list對象,第二個參數是參數列表的第一個參數。3d

 

 

 

va_arg(ap, type)指針

 

一個用於取出參數的宏,這個宏的第一個參數是va_list對象,第二個參數是要取出的參數類型。code

 

 

va_end(ap)對象

 

這個宏用於關閉取參列表內存

 

2、多參函數的取參原理

在編寫咱們本身的多參函數以前,明白函數的取參原理是十分重要的,首先,函數的參數是被放入咱們內存的棧段的,並且放入的順序是從後往前放入,好比若是一個函數參數以下:it

void func(int a,int b,int c,int d)

那麼傳遞參數的時候參數d先入棧,接着是c、b、a。如此這樣,在取參的時候,根據堆棧的取值原則,則取值順序爲a、b、c、d。因此在原理上,只要咱們知道第一個參數的地址和每一個參數的類型,咱們就能夠將參數都取出來。而上面介紹的幾個宏,就是幫助咱們作這些的。
 

3、聲明與實現省略參數的多參函數

"..."這個符號就是咱們用來實現省略參數函數的符號。例如咱們模擬實現一個log函數以下:

-(void)myLog:(NSString *)str,...{//省略參數的寫法
    va_list list;//建立一個列表指針對象
    va_start(list, str);//進行列表的初始化,str爲省略前的第一個參數,及...以前的那個參數
    NSString * temStr = str;
    while (temStr!=nil) {//若是不是nil,則繼續取值
         NSLog(@"%@",temStr);
         temStr = va_arg(list, NSString*);//返回取到的值,而且讓指針指向下一個參數的地址
    }
    va_end(list);//關閉列表指針
}

注意,調用時,咱們必須在參數的最後加上nil這個判斷結束的條件:

[self myLog:@"312",@"321", nil];//必須有nil

4、一點補充

細心的你可能發現了,這裏的nil是咱們在調用函數時手動加上的,但是系統的許多函數在咱們調用時,系統直接幫咱們加上了參數結尾的那個nil,例如

 

 NSArray * array = [NSArray arrayWithObjects:(id), nil]

這是如何作到的呢?咱們只須要在函數的聲明裏加上一個宏,就能夠實現這個功能,修改以下:

-(void)myLog:(NSString *)str,...NS_REQUIRES_NIL_TERMINATION{//這裏加上一個宏
    va_list list;
    va_start(list, str);
    NSString * temStr = str;
    while (temStr!=nil) {
         NSLog(@"%@",temStr);
         temStr = va_arg(list, NSString*);
    }
    va_end(list);
}

顧名思義,這個宏的做用就是在結束位置加上咱們須要的nil。

專一技術,熱愛生活,交流技術,也作朋友。

——琿少 QQ羣:203317592

相關文章
相關標籤/搜索