The swap class actively calls the +(void)load method

Our MethodSwizzled swaps in the +(void)load method, and if it is actively called somewhere else the previously swapped methods will be swapped back, so there is no swap.

The solution is to use a simple design pattern that ensures that code exchanged by methods is executed only once.

The swapped methods are superclass methods

If the swapped method is a method of the parent class, this will cause the parent class to report an error when calling the method, because the parent class does not have the swapped method in the child class. Solution:

  • Try adding methods to swap for yourself first.
  • Then give the IMP of the parent class to Swizzle.
+ (void)lg_betterMethodSwizzlingWithClass:(Class)cls oriSEL:(SEL)oriSEL swizzledSEL:(SEL)swizzledSEL{
    
    if(! cls) NSLog(@"The exchange class passed in cannot be empty"); Method oriMethod = class_getInstanceMethod(cls, oriSEL); Method swiMethod = class_getInstanceMethod(cls, swizzledSEL); // Try adding BOOL success = class_addMethod(CLS, oriSEL, method_getImplementation(swiMethod), method_getTypeEncoding(oriMethod));if(success) { So just replace class_replaceMethod(CLS, swizzledSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)); }else{// implementations has a direct exchange of method_exchangeImplementations(oriMethod, swiMethod); }}Copy the code

The method of exchange does not exist

If the method to be exchanged does not exist, then the exchange will fail. At this time, we need to add another judgment on the basis of the above, which is before the method exchange is performed.

+ (void)lg_bestMethodSwizzlingWithClass:(Class)cls oriSEL:(SEL)oriSEL swizzledSEL:(SEL)swizzledSEL{
    
    if(! cls) NSLog(@"The exchange class passed in cannot be empty");
    
    Method oriMethod = class_getInstanceMethod(cls, oriSEL);
    Method swiMethod = class_getInstanceMethod(cls, swizzledSEL);
    
    if(! oriMethod) { class_addMethod(cls, oriSEL, method_getImplementation(swiMethod), method_getTypeEncoding(swiMethod)); method_setImplementation(swiMethod, imp_implementationWithBlock(^(id self, SEL _cmd){ })); } BOOL didAddMethod = class_addMethod(cls, oriSEL, method_getImplementation(swiMethod), method_getTypeEncoding(swiMethod));if (didAddMethod) {
        class_replaceMethod(cls, swizzledSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
    } else{ method_exchangeImplementations(oriMethod, swiMethod); }}Copy the code