Objective-C可變參數的函數實現,objective-c可變

來源:互聯網
上載者:User

Objective-C可變參數的函數實現,objective-c可變
1.前言

相信接觸過OC的對NSLog都很熟悉,細心查看NSLog的原始定義,會發現,他的原型如下:

FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);

路徑在:OS X version/Frameworks/Foundation/NSObjCRuntime.h

注意到參數最後的...,這裡是可變參數。這樣,在調用時就可以根據需要傳入相應個數的參數了。

PS:其實在C#中也有params指定可變參數,跟OC這個很類似。

那麼,如何在自己寫的函數中實現可變參數呢?

2.實現

要實現OC中的可變參數,需要幾個宏定義va_list、va_start、va_arg、va_end,先實現效果,以無限個整數相加為例:

RandomArgs.h

#import <Foundation/Foundation.h>@interface RandomArgs : NSObject-(int)add:(int)item,...;@end

RandomArgs.m

#import "RandomArgs.h"@implementation RandomArgs-(int)add:(int)item,...{    va_list list;    va_start(list, item);    int result=0;     NSLog(@"第一個參數:%d",item);    result+=item;    int arg;    while ((arg=va_arg(list,int))) {         NSLog(@"當前參數:%d",arg);        result+=arg;    }    va_end(list);    return result;}@end

main.m

#import <Foundation/Foundation.h>#import "RandomArgs.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        RandomArgs* rand=[[RandomArgs alloc]init];        int result=[rand add:4,5,6,nil];        NSLog(@"結果:%d",result);    }    return 0;}

效果

3.總結

主要是通過迴圈va_arg來擷取,但是要注意的是,第一個參數必須是固定的,迴圈裡面只能擷取第二個參數以後的參數。

主要參數解釋:

參數 路徑、原型、解釋
va_list OS X version/usr/include/sys/_types/_va_list.h/typedef__darwin_va_list va_list;,這個變數是指向參數地址的指標,因為得到參數的地址之後,再結合參數的類型,才能得到參數的值。
va_start stdarg.h#define va_start(ap, param) __builtin_va_start(ap, param),第一個選擇性參數地址
va_arg stdarg.h#define va_arg(ap, type) __builtin_va_arg(ap, type),下一個參數地址
va_end stdarg.h#define va_end(ap) __builtin_va_end(ap),將指標置為無效
4.原理

參數在堆棧中分布,位置

在進程中,堆棧地址是從高到低分配的.當執行一個函數的時候,將參數列表入棧,壓入堆棧的高地址部分,然後入棧函數的返回地址,接著入棧函數的執行代碼,這個入棧過程,堆棧地址不斷遞減,一些駭客就是在堆棧中修改函數返回地址,執行自己的代碼來達到執行自己插入的程式碼片段的目的。

總之,函數在堆棧中的分布情況是:地址從高到低,依次是:函數參數列表,函數返回地址,函數執行程式碼片段。

堆棧中,各個函數的分布情況是倒序的.即最後一個參數在列表中地址最高部分,第一個參數在列表地址的最低部分.參數在堆棧中的分布情況如下:

最後一個參數

倒數第二個參數

...

第一個參數

函數返回地址

函數程式碼片段

轉載請註明:特維部落格 » Objective-C可變參數的函數實現

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.