Preface
Everyone should understand that there are two ways to directly call an object in iOS: one is performSelector:withObject; the other is NSInvocation.
The first method is relatively simple and can complete simple calls. However, for >2 parameters or return values,performSelector:withObject
It seems a bit powerless, so in this case, we can use NSInvocation to perform these relatively complex operations
Basic use of NSInvocation
Method signature class
// The method signature saves the method name/parameter/return value, and cooperates with NSInvocation to forward messages.// Method signature is generally used to set parameters and get the return value, and has no much relationship with the method call//1. Initialize NSMethodSignature according to the methodNSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(run:)];
Create an NSInvocation object based on method signature
// The object/method name/parameter/return value to which the method belongs is saved in NSInvocation//In fact, NSInvocation is to turn a method into an object//2. Create an NSInvocation objectNSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; //Set the method caller = self; //Note: The method name here must be consistent with the method in the method signature class = @selector(run:); NSString *way = @"byCar"; //The Index here starts from 2, thinking that 0 and 1 have been occupied, namely self (target) and selector (_cmd)[invocation setArgument:&way atIndex:2]; //3. Call the invoke method[invocation invoke]; //Implementing run: method- (void)run:(NSString *)method{ }
optimization
However, the above method has many disadvantages, first let's solve it one by one
1. If the called method does not exist
//At this time we should judge whether the method exists. If this does not exist, this throws an exceptionif (signature == nil) { //aSelector is the method passed inNSString *info = [NSString stringWithFormat:@"%@ method not found", NSStringFromSelector(aSelector)]; [NSException raise:@"Exception occurred in method call" format:info, nil]; }
2. The number of parameters of the method does not match the number of parameter array elements transmitted from the outside world.
//The parameters cannot be set by traversing the parameter array here, because the number of parameters transmitted from the outside world is uncontrollable// Therefore, the number of parameters obtained through the numberOfArguments method includes self and _cmd, and then compare the parameters required by the method with the number of parameters passed in from the outside world, and take the minimum value between themNSUInteger argsCount = - 2; NSUInteger arrCount = ; NSUInteger count = MIN(argsCount, arrCount); for (int i = 0; i < count; i++) { id obj = objects[i]; // Determine whether the parameter to be set is NSNull, if so, set to nil if ([obj isKindOfClass:[NSNull class]]) { obj = nil; } [invocation setArgument:&obj atIndex:i + 2]; }
3. Determine whether the currently called method has a return value
//Method 1:id res = nil; if ( != 0) {//There is a return value // Assign the return value to res [invocation getReturnValue:&res]; } return res; //Method 2://You can obtain the returned type encoding,Therefore, the specific type of return value can be inferred
Summarize
The above is the entire content of this article. I hope that the content of this article has a certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.