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