Common mistakes in development
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController function]: unrecognized selector sent to instance 0x7fdd10d17e00'
Copy the code
This means that the function method is not implemented, as is common in.h where methods are declared, but.m where methods are not implemented, or
[self performSelector:NSSelectorFromString(@"function")];
Copy the code
The code for this string generation method,
Unrecognized selector that sent to instance 0 x7fdd10d17e00 ‘because methodSignatureForSelector this method, because had not found the run the corresponding implementation method, So it returns an empty method signature, which eventually causes the program to crash with an error that Xcode will not throw, and OC will give you three chances to save
Method 1: dynamic parsing
Declare alternate method
void function(id sf,SEL cd){
NSLog(@"% @",sf);
NSLog(@"% @",NSStringFromSelector(cd));
}
Copy the code
Perform dynamic method resolution by adding methods to objects at run time
+(BOOL)resolveInstanceMethod:(SEL)sel
{
if (sel == @selector(function)) {
class_addMethod(self, sel, (IMP)function."v@:");
}
return [super resolveInstanceMethod:sel];
}
Copy the code
The execution of such a method is forwarded to the alternative method
Method 2: Fast forwarding if this instance cannot find the implementation of the method, you can forward the message to the object that implements the method
An instance of an implementation method
@implementation Function
-(void)function
{
NSLog(@"do function");
}
@end
Copy the code
Implementing fast message forwarding The return value of this method is the object executing the method not found
-(id)forwardingTargetForSelector:(SEL)aSelector
{
Function *fun = [[Function alloc]init];
if ([fun respondsToSelector:aSelector]) {
return fun;
}
return [super forwardingTargetForSelector:aSelector];
}
Copy the code
The fun object then executes the -(void)function method
Method 3: Standard message forwarding
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
if (aSelector == @selector(function)) {
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return [super methodSignatureForSelector:aSelector];
}
-(void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL selector = [anInvocation selector];
Function *fun1 = [[Function alloc]init];
Function *fun2 = [[Function alloc]init];
if ([fun1 respondsToSelector:selector]) {
[anInvocation invokeWithTarget:fun1];
}
if([fun2 respondsToSelector:selector]) { [anInvocation invokeWithTarget:fun2]; }}Copy the code
MethodSignatureForSelector: used to generate the method signature, the signature is to give forwardInvocation: the parameters in the anInvocation calls. In method 3 we create our own method signature and use the same object in the forwardInvocation to invoke the corresponding signature, which also implements message forwarding.
Method 2 and Method 3 are both message forwarding. Method 2 is simple and fast, but can only forward the message to one object. Method 3 is complex and slow, but can forward the message to multiple objects