国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Objective-C可變參數的函數實現

2019-11-14 18:50:52
字體:
來源:轉載
供稿:網友

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_listOS X version/usr/include/sys/_types/_va_list.h/typedef__darwin_va_list va_list;,這個變量是指向參數地址的指針,因為得到參數的地址之后,再結合參數的類型,才能得到參數的值。
va_startstdarg.h#define va_start(ap, param) __builtin_va_start(ap, param),第一個可選參數地址
va_argstdarg.h#define va_arg(ap, type) __builtin_va_arg(ap, type),下一個參數地址
va_endstdarg.h#define va_end(ap) __builtin_va_end(ap),將指針置為無效

4.原理

參數在堆棧中分布,位置

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

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

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

最后一個參數

倒數第二個參數

...

第一個參數

函數返回地址

函數代碼段

轉載請注明:特維博客 » Objective-C可變參數的函數實現


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永仁县| 通州市| 南丰县| 那曲县| 阿巴嘎旗| 建宁县| 哈尔滨市| 连江县| 吴堡县| 兴城市| 衡东县| 昌都县| 桓台县| 南充市| 洛宁县| 怀远县| 广昌县| 灵台县| 华蓥市| 云浮市| 广昌县| 沐川县| 新竹市| 沙洋县| 同心县| 天水市| 蕉岭县| 襄垣县| 漳浦县| 桦南县| 鹤峰县| 大新县| 中西区| 阿勒泰市| 和政县| 水富县| 阳曲县| 清新县| 阿坝| 宁化县| 新昌县|