OC中的可變參數(shù)

一、使用場景

? ? ? ?有時候我們需要自定義一個方法來實現(xiàn)一些功能,(比如:暴打小卷),我們的方法里面需要指定來暴打小卷,打小卷的人數(shù)不確定,打小卷的是不是人也無法確定,所以我們需要用到可變參數(shù)。

二、簡單介紹

? ? ? ?簡單來說,可變參數(shù)就是我們在自定義方法的時候,傳遞的參數(shù)類型,參數(shù)個數(shù)可以根據(jù)需要來改變。實現(xiàn)像下面這樣去調(diào)用這個方法:第一個參數(shù)固定,其它參數(shù)類型不同,參數(shù)個數(shù)也不一樣。當(dāng)然,我們定義兩個方法也可以實現(xiàn),但是如果李成鵬每次打小卷帶的小弟都不一樣的話呢?

[self 暴打小卷 : 李成鵬,王冬,尉超,貓,狗,nil];

[self 暴打小卷 : 李成鵬,張洪林,王鼎,豬,nil];

三、可變參數(shù)的實現(xiàn)原理

1.在C中,當(dāng)我們無法列出傳遞函數(shù)的所有實參的類型和數(shù)目時,可以用省略號指定參數(shù)表,OC中自然也可以這么玩:

- (void)暴打小卷:(人 *)李成鵬, ...;

2.函數(shù)的參數(shù)在內(nèi)存中是以的形式存儲的,存儲順序是按照參數(shù)從右往左的順序依次入棧,根據(jù)棧的先進后出的特性,接下來取參數(shù)的時候就是從左向右的

順序依次取值了。從理論上講,只要取到了其中一個參數(shù)的地址,“順藤摸瓜"總能找到其它的參數(shù)地址。所以,需要將第一個參數(shù)固定。根據(jù)第一個參數(shù)的地址,來取到其它的參數(shù)。

3.在寫具體的實現(xiàn)方法之前,我們需要用到C庫里面的幾個”工具“來”暴打小卷“(動家伙,打扁他^_^)。這些工具有:刀、槍、棍、棒。。。(⊙o⊙)…其實是:

typedef char *?va_list :這是一個字符類型的指針,指針指向當(dāng)前的參數(shù),需要通過這個指針取參數(shù)。

void va_start(va_list ap,param) :初始化字符指針的函數(shù),將指針指向方法中的第一個可變參數(shù),這個函數(shù)需要兩個參數(shù):va_list和自定義的方法中固定的那個參數(shù)(比如暴打小卷中的“李成鵬”)

type va_arg(va_list ap,type):這是一個取參數(shù)的函數(shù),這個函數(shù)需要兩個參數(shù),第一個參數(shù)是字符指針va_list,第二個參數(shù)是我們需要取的可變參數(shù)的數(shù)據(jù)類型。這個函數(shù)需要做兩件事:1:取到指定數(shù)據(jù)類型的參數(shù)。2:將指針ap指向下一個可變參數(shù)的地址。

void va_end(va_list ap):當(dāng)我們?nèi)⊥晁械目勺儏?shù)之后,需要將指針ap指向NULL。不然它就可能嚇JB亂指,就成了一個野孩子:野指針。這個函數(shù)需要和va_start成對使用。

4.通過上面第三條說的,其實實現(xiàn)可變參數(shù)的步驟已經(jīng)顯而易見了:

1、定義一個va_list指針,用來指向打小卷的兇手們。警察開始立案調(diào)查%>_<%。

2、調(diào)用 va_start 初始化這個指針,首先指向打小卷的幕后主使(李成鵬)抓到他之后就能抓到其他兇手。

3、調(diào)用 va_arg 開始取參數(shù),主使抓到了,小弟們自然跑不掉。

4、調(diào)用 va_end 將va_list指針置空??梢越Y(jié)案了O(∩_∩)O~~。

四、具體實現(xiàn)

不多說,直接上代碼實例:

// 定義一個方法

-(void)暴打小卷:(人*)主使,...{

// 定義指針

va_list ap;

// 開始取值,指針先確定主使人

va_start(ap,主使);

NSLog(@"打小卷的主使是:%@",主使);

// 循環(huán)取值

while(YES){

// 因為不確定參數(shù)的類型,所以指定數(shù)據(jù)類型是id類型,并且用id類型的變量來接收。

id obj=va_arg(ap,id);

// 取完所有參數(shù)之后,跳出循環(huán)

if(obj==nil)break;

NSLog(@"打小卷的幫兇有:%@",obj);

}

// 取完之后毀掉va_list指針

va_end(ap);

}

調(diào)用:簡單介紹里面已經(jīng)寫了調(diào)用的示例,需要注意的是,參數(shù)的結(jié)尾必須寫上nil來讓取參數(shù)的時候的循環(huán)停止。當(dāng)然機智的你或許有其他的辦法來控制循環(huán)次數(shù),就不需要寫最后的nil了。比如對sql語句的?進行賦值的時候,可以判斷問號的個數(shù)來控制循環(huán)次數(shù)。

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容