獲取可變參數(shù)的方法

在看 YTKNetwork 源碼的時候,看到下面的 YTKLog 定義(刪除了部分代碼):

void YTKLog(NSString *format, ...) {
#ifdef DEBUG
    va_list argptr;
    va_start(argptr, format);
    NSLogv(format, argptr);
    va_end(argptr);
#endif
}

接下來對下面的代碼進行解析。

可變參數(shù)

當我們無法列傳遞給函數(shù)的所有的實參類型和數(shù)目時,可以用省略號指定參數(shù)列表。例如 NSLog 的定義:

void NSLog(NSString *format, ...);

函數(shù)參數(shù)傳遞的原理

函數(shù)參數(shù)時,參數(shù)存放在內存的堆棧段中,在函數(shù)執(zhí)行的時候,以數(shù)據(jù)結構的形式進行傳遞的,從右至左依次入棧。舉個例子:

void func(int x, float y, char z);

在函數(shù)調用的時候,實參 char z 先進棧,然后時 float y ,最后時 int x ,因此在內存中的變量存放依次是 x -> y -> z ,因此,從理論上說,我們只要探測到任意一個變量的地址,并且知道其他變量的類型,通過指針位移運算,就可以順藤摸瓜的找到其他變量了。

相關宏定義

typedef char* va_list;

va_list 是一個字符指針,可以理解為指向當前參數(shù)的一個指針,取參必須通過這個指針進行。

void va_start ( va_list ap, prev_param ); /* ANSI version */

ap 進行初始化,讓它指向可變參數(shù)表里面的第一個參數(shù),第一個參數(shù)是 va_list 類型的指針,第二個參數(shù) prev_param 是在變參表前面緊挨著的變量,即 “…” 之前的那個參數(shù)。

type va_arg(va_list ap, type);

獲取參數(shù),第一個參數(shù)是 ap,第二個參數(shù) type 是獲取指定參數(shù)的類型,然后返回這個指定的類型的值,并且把 ap 指向可變參數(shù)的下一個變量的位置。

void va_end( va_list ap );

獲取所有的參數(shù)之后,我們必須將這個 ap 指針關閉,以避免發(fā)生危險。它將輸入的參數(shù) ap 置為 NULL。通常 va_startva_end 是成對出現(xiàn)的。

以下是 NSLogv 的定義,一個是說明格式化的字符串 format,一個是可變參數(shù)的指針 args。

void NSLogv(NSString *format, va_list args);

實例

以下是一個可變參數(shù)的方法的定義,內部有獲取可變參數(shù)的方法:

- (void)testFunc:(NSString *)parameter1, ... {
    NSString *parameter = nil;
    va_list ap;
    va_start(ap, parameter1);
    while (1) {
        parameter = va_arg(ap, NSString *);
        if (!parameter) {
            break;
        }
        NSLog(@"%@", parameter);
    }
}

調用如下:

[self testFunc:@"para", @"one" @"two", @"three", nil];

其他

  • 格式化字符串的要求
NSString *obj = @"A string or other object.";  
NSLog(obj);// 有警告  

注:警告信息:“Format string is not a string literal (potentially insecure)”,說明 NSLog 要求的參數(shù)為字面量,不可為 NSString * 類型。

參考

va_start和va_end使用詳解
OC中的可變參數(shù)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 我們在C語言編程中會遇到一些參數(shù)個數(shù)可變的函數(shù),例如printf() 這個函數(shù),它的定義是這樣的: int pri...
    Mr_Me閱讀 844評論 0 2
  • 一、使用場景 有時候我們需要自定義一個方法來實現(xiàn)一些功能,(比如:暴打小卷),我們的方法里面需要指定誰來暴打...
    MorpLCP閱讀 3,610評論 2 1
  • 1.在C中,變長參數(shù)的函數(shù)即參數(shù)個數(shù)可變、參數(shù)類型不定 的函數(shù)。當我們無法列出傳遞函數(shù)的所有實參的類型和數(shù)目時,以...
    孤獨雜貨鋪閱讀 1,928評論 1 1
  • 昨天晚上臨下班,看到同事因為圖片上傳的問題在那里被吼。 就手癢過去幫一把。 結果改了下tomcat的參數(shù),系統(tǒng)啟動...
    shanggl閱讀 2,995評論 2 1
  • 上次說到,在長達十余年的齊楚爭霸中,楚國雖無霸主之名,卻日益強大,勢力漸漸深入到淮泗地區(qū),令中原諸國感到十分憂慮。...
    信陵飲閱讀 1,228評論 2 50

友情鏈接更多精彩內容