<p align= "center" >
</p>
iOS development Method swizzling in layman's
As long as the use of Google, there are many online Method Swizzling
demo, here I do not intend to post code, the main introduction of the concept, principles, precautions and so on.
Development Requirements
If the product manager suddenly says, "Add statistical functionality to all pages, that is, users enter this page to count once." We will think of some of the following methods:
Directly and simply rude in each controller to add statistics, copy, paste, copy, paste ...
The above method is too low, consumes time and is very difficult to maintain later, it will let the developers in the back scold dead.
We can use inheritance to solve this problem. Create a base class, add a statistical method to the base class, and other classes inherit from the base class.
However, this modification is still very large, and the customization is poor. After a new person joins, it is not advisable to instruct them to inherit from this base class.
We can UIViewController
build one Category
, and then introduce this in all the controllers Category
. Of course we can also add a PCH
file and add it Category
to the PCH
file.
We can use Apple's "black Magic" Method Swizzling
, which Method Swizzling
is essentially IMP
a pair and SEL
exchange.
Learn a few concepts first selectors, Methods, & implementations
In Objective-C
the runtime,,, selectors
methods
refers to implementations
different concepts, but we usually say that during the message sending process, these three concepts can be converted to each other. Here is Objective-C Runtime Reference
the description of the Apple:
-
Selector (typedef struct OBJC_SELECTOR *sel)
: At run time selectors
is used to represent the name of a method. Selector
is a type C string that is registered (or mapped) at run time. Selector
is generated by the compiler and is automatically mapped by the runtime for name and implementation when the class is loaded into memory.
-
method (typedef struct OBJC_METHOD *method)
: Method is an opaque type used to represent the definition of a method.
-
Implementation (typedef ID (*IMP) (ID, SEL,...)
: This data type points to the beginning of the implementation of a method. This method is implemented for the current CPU architecture using standard C method calls. The first parameter of the method points to itself of the calling method (that is, an instance object of the in-memory class, or, if the class method is called, a pointer to a meta-class object ( metaclass
). The second parameter is the name of the method selector
, and the true parameters of the method are immediately followed.
Understand that the selector
method
implementation
best way to relate these three concepts is that, at run time, the Class ( Class
) maintains a message distribution list to resolve the correct delivery of the message. The entry for each message list is a method ( Method
), which maps a pair of key-value pairs where the key value is the name of the method selector(SEL)
, and the value is a pointer to the function implemented by the method implementation(IMP)
. Method swizzling
modified the message distribution list for the class so that an selector
existing mapping was made to another implementation implementation
, while renaming the implementation of the native method as a new one selector
.
Method swizzling Principle
Method Swizzing
Occurs at run time and is used primarily to swap two at run time Method
, we can Method Swizzling
write code anywhere, but only after this code has been Method Swilzzling
executed.
Method swizzling using notice cluster design pattern
These classes, such as NSNumber, Nsarray, Nsdictionary, and so on in iOS, are class clusters ( Class Clusters
), and a Nsarray implementation may consist of multiple classes.
So if you want to swizzling the Nsarray, you must get to its "true" swizzling, directly to the Nsarray operation is not valid.
The class names of the Nsarray and Nsdictionary classes are listed below, which can be removed from the runtime function.
class name |
Mami |
Nsarray |
__nsarrayi |
Nsmutablearray |
__nsarraym |
Nsdictionary |
__nsdictionaryi |
Nsmutabledictionary |
__nsdictionarym |
Attention points
- Swizzling should always be
+load
executed in the
- Swizzling should always be
dispatch_once
executed in the
+load
do not invoke when swizzling is executing in [super load]
. If multiple calls [super load]
, there may be "swizzle invalid" illusion, the principle is as follows:
Use Method swizzling in Swift custom classes
There are two necessary conditions to use Method swizzling in a Swift custom class:
- Classes that contain Swizzle methods need to inherit from NSObject
- The method that needs to be swizzle must have dynamic properties (attribute)
Note: For Swift's custom classes, because the OBJECTIVE-C runtime is not used by default, there is no dynamically distributed method list, so if you want to swizzle a swift type method, you need to add the original method and the replacement method to the dynamic tag. To indicate that they need to use a dynamic distribution mechanism. Of course the class also inherits from NSObject.
Note: The following example uses OBJECTIVE-C dynamic distribution, which can be used directly for NSObject subclasses (Uiviewcontroller), not custom classes in Swift, so it is also possible to have no dynamic tag.
Similarities and differences of Objective-c and Swift in Method swizzling
difference |
objective-c |
Swift |
Runtime header File |
#import <objc/runtime.h> |
Don't need |
Swizzling Call Place |
load Method |
initialize Method |
Note: The load
method is only available in the objective-c, and cannot be overloaded in Swift, regardless of how the test will be reported compile errors. The next best place to execute Swizzle is the initialize
place before the first method is called.
Because swizzling will change the global state, we need to take some precautions at runtime. GCD guarantees the atomicity of the operation, ensuring that the dispatch_once
code is executed only once, regardless of the number of threads.
Method swizzling Practical Application APM (Applied performance Management)
The principle of network monitoring, should be hook NSURLConnection
, NSURLSession
. The principle of crash collection should be hook NSException
.
- https://newrelic.com/
国外行业老大
- http://www.tingyun.com/
国内听云
- http://www.oneapm.com/
国内OneAPM
- http://apm.netease.com/
国内网易
Overseas information
iOS development Method swizzling in layman's