歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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

在Object-C中,我們經常會遇到一類參數數量不定的函數,如NSLog(NSString *format, ...)。像這類的函數時如何實現的呢?這篇博客將給你答案。

引語:

在Object-C中,我們會遇到很多像NSLog這樣的函數,其中參數的個數不確定,由程序員自由控制,在初始化數組,字典等方面應用廣泛,那麼,這類的函數是如何實現的呢?我們怎麼編寫我們自己的省略參數的函數呢?當然,這不是唯一的多參函數的處理方法,你也可以通過一個字典或者數組傳遞參數。但C為我們提供的這樣的一種機制,無疑是最方便的。
 
一、了解幾個概念

va_list

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

va_start(ap,param)

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

va_arg(ap, type)

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

va_end(ap)

這個宏用於關閉取參列表

二、多參函數的取參原理

在編寫我們自己的多參函數之前,明白函數的取參原理是十分重要的,首先,函數的參數是被放入我們內存的棧段的,而且放入的順序是從後往前放入,比如如果一個函數參數如下:

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

那麼傳遞參數的時候參數d先入棧,接著是c、b、a。如此這樣,在取參的時候,根據堆棧的取值原則,則取值順序為a、b、c、d。所以在原理上,只要我們知道第一個參數的地址和每個參數的類型,我們就可以將參數都取出來。而上面介紹的幾個宏,就是幫助我們做這些的。
 
三、聲明與實現省略參數的多參函數

"..."這個符號就是我們用來實現省略參數函數的符號。例如我們模擬實現一個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
 
四、一點補充


細心的你可能發現了,這裡的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。

Objective-C中@property的所有屬性詳解 http://www.linuxidc.com/Linux/2014-03/97744.htm

Objective-C 和 Core Foundation 對象相互轉換的內存管理總結 http://www.linuxidc.com/Linux/2014-03/97626.htm

使用 Objective-C 一年後我對它的看法 http://www.linuxidc.com/Linux/2013-12/94309.htm

10個Objective-C基礎面試題,iOS面試必備 http://www.linuxidc.com/Linux/2013-07/87393.htm

Objective-C適用C數學函數 <math.h> http://www.linuxidc.com/Linux/2013-06/86215.htm

好學的 Objective-C 高清PDF http://www.linuxidc.com/Linux/2014-09/106226.htm

Copyright © Linux教程網 All Rights Reserved