Objective-C Variable Parameter Function implementation, objective-c variable
1. Preface
I believe that those who have been familiar with OC are familiar with NSLog. By carefully checking the original definition of NSLog, we will find that its prototype is as follows:
FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
The path is:OS X version/Frameworks/Foundation/NSObjCRuntime.h
Note that the final parameter... is a variable parameter. In this way, you can input a number of parameters as needed.
PS: in fact, in C #, params also specifies variable parameters, which is similar to OC.
So, how do I implement variable parameters in a self-written function?
2. Implementation
To implement variable parameters in OC, several macros are required to define va_list, va_start, va_arg, and va_end. The following example shows how to add infinite integers:
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 (@ "first parameter: % d", item); result + = item; int arg; while (arg = va_arg (list, int) {NSLog (@ "current parameter: % 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 (@ "result: % d", result);} return 0 ;}
Effect
3. Summary
It is mainly obtained through the loop va_arg, but note that the first parameter must be fixed, and only parameters after the second parameter can be obtained in the loop.
Main Parameter explanation:
Parameters |
Path, prototype, and explanation |
Va_list |
OS X version/usr/include/sys/_types/_va_list.h/typedef ,__darwin_va_list va_list; , This variable is a pointer to the parameter address, because after obtaining the parameter address, combined with the parameter type, the parameter value can be obtained. |
Va_start |
stdarg.h ,#define va_start(ap, param) __builtin_va_start(ap, param) , The first optional parameter address |
Va_arg |
stdarg.h ,#define va_arg(ap, type) __builtin_va_arg(ap, type) , Next parameter address |
Va_end |
stdarg.h ,#define va_end(ap) __builtin_va_end(ap) , Set the pointer to invalid |
4. Principles
Parameter distribution in the stack, location
In the process, stack addresses are allocated from high to low. when a function is executed, the parameter list is pushed into the stack, the high address of the stack, the return address of the function, and the Execution Code of the function, during the stack import process, the stack address is constantly decreasing. Some hackers modify the function return address in the stack and execute their own code to execute their own inserted code segments.
In short, the distribution of functions in the stack is: address from high to low, in turn: function parameter list, function return address, function Execution Code segment.
In the stack, the distribution of each function is in reverse order. that is, the highest part of the last parameter in the list, and the first parameter in the lowest part of the list address. the parameter distribution in the stack is as follows:
Last Parameter
Second to last parameter
...
First Parameter
Function return address
Function Code segment
Reprinted, please note: tewei blog» Objective-C Variable Parameter Function implementation