1. Preface
believe that contact with OC is very familiar to NSLog, carefully review the original definition of NSLog, will find that his prototype is as follows:
FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
Path in:OS X version/Frameworks/Foundation/NSObjCRuntime.h
Note that the last parameter of ..., here is the variable parameter. This allows you to pass in the corresponding number of arguments as needed at the time of invocation.
PS: In fact, there is a params in C # that specifies variable parameters, similar to OC.
So, how do you implement variable parameters in your own functions?
2. Implement
To implement variable parameters in OC, you need several macros to define Va_list, Va_start, Va_arg, Va_end, to implement the effect first, and to add an infinite number of integers as an example:
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); IntResult=0; NSLog(@"First parameter:%d",Item);Result+=Item; IntArg; While arg=va_arg ( list,int)) { nslog (@ "current parameter:%d" Span class= "pun" >,arg) Result+=arg;} Va_end (list return Result;} @end
Main.m
#import <Foundation/Foundation.h>#import "RandomArgs.h"IntMain(Intargc, Const Char *Argv[]) { @autoreleasepool { Randomargs*Rand=[[randomargs Alloc] int Result=[rand add< Span class= "pun" >:4,5 6,nil]; nslog (@ "Result:%d" , Result } return 0; /span>
Effect
3. Summary
Mainly through the loop va_arg to get, but note that the first parameter must be fixed, the loop can only get the second parameter after the argument.
Main parameter explanation:
Parameters |
paths, prototypes, interpretations |
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 address of the parameter, because the value of the parameter can be obtained after the address of the parameter is combined with the type of the parameter. |
Va_start |
stdarg.h , #define va_start(ap, param) __builtin_va_start(ap, param) the first optional parameter address |
Va_arg |
stdarg.h , the #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. Principle
The parameters are distributed in the stack, and the position
In the process, the stack address is allocated from high to low. When a function is executed, the argument list is put into the stack, pushed into the high address portion of the stack, and then into the return address of the stack function, and then into the execution code of the stack function, this into the stack process, the stack address is constantly decreasing, some hackers are in the stack Execute your own code to achieve the purpose of executing your own inserted code snippet.
In short, the distribution of functions in the stack is: address from high to low, in order: function parameter list, function return address, function execution code snippet.
In the stack, the distribution of functions is reversed. That is, the last parameter is in the highest part of the list, the first parameter is in the lowest part of the list address. The parameters are distributed in the stack as follows:
Last parameter
The second-lowest parameter
...
First parameter
function return address
Function Code Snippet
Reprint Please specify: Special Dimension blog»objective-c function realization of variable parameters
function implementation of OBJECTIVE-C variable parameters