Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Method Swizzling

Method Swizzling, as the name suggests, is the implementation of swapping two methods. To put it simply, you take advantage of the dynamic binding features of Objective-C Runtime to swap one method implementation with another.

objc_class

In objective-C Runtime, a class is represented by a structure called objc_class, which is defined as follows:

objc_method_list

From the above structure you can see an objc_method_list pointer that holds a list of all the methods of the current class. Objc_method_list, meanwhile, is a structure defined as follows:

objc_method

We found an objc_method field in the above structure, which is defined as follows:We also see from the above structure that a method consists of the following three parts.

  • Method_name: indicates the method name.
  • Method_types: Method types.
  • Method_imp: method implementation.

Exchange principle

Use Method Swizzling exchange Method, is actually changed the mthod_imp objc_method structure, namely changed method_name and method_imp mapping relationship is as follows:

Implement Method Swizzling correlation function

Method class_getInstanceMethod(Class_Nullable aClass,SEL_Nonnull aSelector) OBJC_AVAILABLE(10.0,2.0,9.0,1.0,2.0);

  • Function: Returns an instance method of the target class aClass with the method name aSelector.
  • Parameters that
    • AClass: Target class.
    • ASelector: method name.

Note that NULL is returned only if neither the current class nor its parent class contains the specified method.

BOOL class_addMethod(Class_Nullable aClass,SEL_Nonnull aSelector,IMP_Nonnullimp,const char * _Nullable types) OBJC_AVAILABLE (10.5, 2.0, 9.0, 1.0, 2.0);

  • Function: Add a new method to the target class aClass, including the implementation of the method.

  • Parameters that

    • AClass: Target class.
    • ASelector: Method name to which the method is to be added.
    • Imp: Method implementation to add methods.
    • Types: Encoding type of method implementation.

Note that the method was successfully added to the target class. Returns a failure indicating that a method with the same method name already exists in the target class.

IMP getimplementation (Method_Nonnull method) OBJC_AVAILABLE (10.5,2.0,9.0,1.0,2.0);

  • Function: Returns a pointer to a method implementation.

  • Parameters that

    • Method: Indicates the target method.

IMP class_replaceMethod(Class_Nullable aClass,SEL_Nonnull aSelector,IMP_Nonnull imp,const char * _Nullable types) OBJC_AVAILABLE (10.5, 2.0, 9.0, 1.0, 2.0);

  • Function: Replace the finger of the aSelector method of the target class aClass.
  • Parameters that
    • AClass: Target class.
    • ASelector: Method name of the current method.
    • Imp: Method implementation of a new method.
    • Types: Encoding type of method implementation.

Void method_exchangeImplementations(Method_Nonnull M1,Method_Nonnull m2) OBJC_AVAILABLE(10.5,2.0,9.0,1.0,2.0);

  • Function: Swaps implementation Pointers to two methods.
  • Parameters that
    • M1: Switch method 1.
    • M2: switch method 2
#import <objc/runtime.h> @implementation NSObject (Swizzler) + (BOOL)sensorsdata_swizzleMethod:(SEL)originalSEL WithMethod :(SEL)alternateSEL {// get the originalMethod originalMethod = class_getInstanceMethod(self, originalSEL); if (! originalMethod) { return NO; } // Get Method alternateMethod = class_getInstanceMethod(self, alternateSEL); if (! alternateMethod) { return NO; } // method_exchangeImplementations(originalMethod, alternateMethod); Return yes; } @endCopy the code