今天在看別人寫的一篇博客的時候,無意間看見了一個這樣的名詞:可變參數函數;瞬間就覺得自己對它一無所知,并且那個作者還說了一句這樣的話:我相信絕大多數即使有著幾年 Objective-C 經驗的讀者,也很難在不查閱資料的前提下正確寫出一個接受可變參數的函數。就是這句話,讓我對這個神秘的 可變參數函數 產生餓極大的興趣。
相信大家都用過這個方法來初始化數組吧!?
NSArray*array=[NSArrayarrayWithObjects:@"123",@"234",@"345",@"456",nil];
里面的arrayWithObjects這個方法,它就是一個可變參數函數,那么什么是可變參數函數呢?顧名思義,它就是可以接受N個參數(N>=0)的函數。
試著自己定義了一個這樣的函數,來展示給大家看:
/**
*? 可變參數函數 (記得在調用的時候要在參數結尾的時候加nil)
*
*? @param statement 隨自己的需要進行類型定義,多個參數,參數類型統一
*
*? @return 隨自己的需要進行類型定義
*/
-(int)variableParameterFunction:(NSString*)statement,...
{
NSMutableArray*argsArray=[[NSMutableArrayalloc]init];
id arg;//定義一個id類型的參數,方便來得到傳入的參數
va_list argList;//定義一個指向個數可變的參數列表指針
if(statement)
{
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)。
[argsArray addObject:statement];//將第一個元素加入到數組中間去,因為雖然指針指向的是第一個元素,但是,在調用下面的va_arg的時候指針又被指向到下一個元素的空間去了,這樣就會錯過一個元素。
while((arg=va_arg(argList,id)))//va_arg(argList,id):返回參數列表中指針arg_ptr所指的參數,返回類型為type,并使指針arg_ptr指向參數列表中下一個參數。
{
[argsArray addObject:arg];
}
NSLog(@"%@",argsArray);
va_end(argList);//清空參數列表,并置參數指針arg_ptr無效。
}
returnargsArray.count;
}
當你在調用這個函數的時候,你可以這樣為參數賦值,
[self variableParameterFunction:@"123",@"234",@"345",@"456",nil];
也可以這樣為參數賦值,
[self variableParameterFunction:@"123",@(234),@"345",@(456),nil];
都不會報錯什么的,只是你在從數組里面取出元素的時候,你得判斷一下是什么類型的,相比于用第一種方法,這第二種調用方法,顯然有點兒不合適了。當然,這些都不重要,重要的是,我們學會了使用這種 絕大多數即使有著幾年 Objective-C 經驗的讀者,也很難在不查閱資料的前提下正確寫出來的 接受可變參數的函數。