Application Scenarios
A large number of controllers in a project need to log statistics or perform similar processing at load-ins. If code is written directly to all controllers, it will produce a lot of duplicated code, which reduces the readability of the code later and is not conducive to maintenance. Because of the same logic code in all parts, in view of this situation, the method swizzling can greatly reduce the coupling degree between the non-main logic code and the controller, which is based on the idea of Slice programming (AOP).
An explanation of AOP concepts (from Baidu Encyclopedia)
In the software industry, AOP is the abbreviation for Aspect oriented programming, which means: face-cutting programming, through the pre-compilation method and runtime dynamic agent to implement the unified maintenance of the program functions of a technology. AOP is a continuation of OOP, a hotspot in software development, an important content in the spring framework, and a derivative model of functional programming. AOP enables the isolation of parts of the business logic, which reduces the coupling between parts of the business logic, improves the reusability of the program, and improves the efficiency of development.
Learn by Demo (Methodswizzling_demo)
1. Create an empty project, and then create a classification (Logging) for the Viewcontroller class in the project.
2. Overload the Viewdidappear: Method in Viewcontroller.
-(void) Viewdidappear: (BOOL) animated {[Super viewdidappear:animated];}
3. If every time the controller is selected by the user, we want to be observed through the output message in the console, then you should add to Viewdidappear:
NSlog (@ "%@", Nsstringfromclass ([Self class]));
The controller to which the view currently displayed by the output device belongs.
4. If the number of controllers that need to be modified in step 3 now is huge, obviously we need to find another way.
5. Import the header file Objc/runtime.h in UIVIEWCONTROLLER+LOGGING.M, now we need to use Method swizzling to deal with this problem.
6. Add a method to the implementation file for the classification
-(void) Swizzled_viewdidappear: (BOOL) animated {[Self swizzled_viewdidappear:animated]; NSLog (@ "%@", Nsstringfromclass ([self class]);}
This method gathers the logic code that we need to add to all the controllers in one place.
7. Continue to implement the following methods in the classification
Void swizzlemethod (Class class, sel originalselector, sel swizzledselector) { method originalmethod = class_ Getinstancemethod (class, originalselector); method swizzledmethod = class_getinstancemethod (Class, swizzledselector); /* judgment class There is a method with originalSelector as the method name. * if not, add to originalSelector as method name, * to swizzledMethod for the implementation of the Method! * if available, do not add. */ /* do not directly method_exchangeImplementations The reason for the substitution: if this class does not implement originalselector, but its parent * class implements, so class_ getinstancemethod will return the method of the parent class. So,method_exchangeimplementations replace * is the method of the parent class   &NBSp; */ bool didaddmethod = class_addmethod ( class, Originalselector, method_getimplementation (Swizzledmethod), method_ Gettypeencoding (Swizzledmethod)); if (Didaddmethod) { class_replacemethod (Class, swizzledselector, method_getimplementatino ( Originalmethod), method_g ettypeencoding (Originalmethod)); } else { method_ Exchangeimplementations (Originalmethod, swizzledmethod); }}
8. In order to use the swizzled_viewdidappear we have written in the classification: replace the Viewdidappear: method in the controller. Use a more special method + (void) load.
In general, the method in the category overrides the same named method in the main class. If there are two categories that implement the same named method, only one method will be called.
But +load: As a special case, when a class is read into memory, runtime sends a +load: message to this class and each of its classifications.
9. Adding in the classification implementation
+ (void) load {Swizzlemethod ([self class], @selector (viewdidappear:), @selector (swizzled_viewdidappear:));}
Swizzlemethod the method named Viewdidappear: And the method named Swizzled_viewdidappear: Two methods of the implementation part of the interchange.
Note: The Viewdidappear in the @selector (viewdidappear:): Method is in the Uiviewcontroller class, not its subclass Viewcontroller.
10. Call procedure See
OBJC Runtime Black Magic-method swizzling