Generally speaking, the method provided by the system is enough to be developed, but sometimes it is difficult to do it with common methods.
such as: Before all the viewcontroll of the Viewwillappear: The method before a log
You might do this:
1. Build a Uiviewcontroll parent class, override the Viewwillappear method, and call the Super Viewwillappear method before adding a log
2. All new Uiviewcontroller inherit the first step of the generated
It is true that you are doing this function, but you have made so many changes, basically every uiviewcontroller to modify the parent class, this method is too cumbersome
This article provides a simple way to implement
In my understanding, Object-c's class invocation method is defined based on three elements.
1. Method, which represents a method type in a class definition (typedef struct OBJC_METHOD *method)
2. SEL selector (typedef struct OBJC_SELECTOR *sel), a method at run-time name, common to have [self performselector: @selector (somemethod:) withobject : Nil afterdelay:0.5]; @selector (SomeMethod:) as the entrance to the method
3. Implementation of the method entry (typedef ID (*IMP) (ID, SEL, ...) )
These three elements determine which function to call specifically
Look directly at the code
[OBJC]View Plaincopyprint?
- #import "Uiviewcontroller+tracking.h"
- #import <objc/runtime.h>
- @implementation Uiviewcontroller (Tracking)
- + (void) load {
- nsstring *classname = Nsstringfromclass (self. Class);
- NSLog (@ "classname%@", classname);
- static dispatch_once_t Oncetoken;
- Dispatch_once (&oncetoken, ^{
- Class class = [self class];
- //When swizzling A-class method, use the following:
- //Class class = Object_getclass ((id) self);
- SEL originalselector = @selector (viewwillappear:);
- SEL swizzledselector = @selector (xxx_viewwillappear:);
- Method Originalmethod = Class_getinstancemethod (class, Originalselector);
- Method Swizzledmethod = Class_getinstancemethod (class, Swizzledselector);
- BOOL Didaddmethod =
- Class_addmethod (class,
- Originalselector,
- Method_getimplementation (Swizzledmethod),
- Method_gettypeencoding (Swizzledmethod));
- if (didaddmethod) {
- Class_replacemethod (class,
- Swizzledselector,
- Method_getimplementation (Originalmethod),
- Method_gettypeencoding (Originalmethod));
- } Else {
- Method_exchangeimplementations (Originalmethod, Swizzledmethod);
- }
- });
- }
Our category overrides the NSObject Load method OC provides the Objc/runtime.h class let's get these things, and also provides the function of the class method operation
We're thinking of replacing the system directly with a method, and then adding some custom actions to the method
We just wanted to run it once enough, so we used Dispatch_once (&oncetoken, ^{...}
Next, add a new method to the class
Replace the new method with the system method
[OBJC]View Plaincopyprint?
- #pragma mark-method swizzling
- -(void) Xxx_viewwillappear: (BOOL) animated {
- NSLog (@ "viewwillappear:%@", self );
- [self xxx_viewwillappear:animated];
- }
But when the new method is implemented, the call is [self xxx_viewwillappear:animated]; Maybe you'll wonder
This is because we have used xxx_viewwillappear and viewwillappear in the above exchange. So the actual implementation is the viewwillappear of the system.
This time maybe you have questions again, why the implementation is-(void) Xxx_viewwillappear: (BOOL) animated{} such a
This is because SEL Swizzledselector = @selector (xxx_viewwillappear:); it's our new way of writing.
Can be combined with this blog to see, map is easy to understand
http://blog.csdn.net/yiyaaixuexi/article/details/9374411
And this one is quite clear about SEL.
http://blog.csdn.net/fengsh998/article/details/8612969
Code
Https://github.com/holysin/Method_swizzle
Method Swizzle black Magic, modifying iOS System Class Library methods (reprint)