SoFunction
Updated on 2025-04-12

Basic Usage Tutorial of NSInvocation in iOS

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:withObjectIt 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.