C is a static language, and it works by means of function calls, so that at compile time we have determined how the program works. While Objective-c is a dynamic language, it does not invoke the method of the class to perform the function, but rather sends a message to the object, and the object will find a matching method to run after receiving the message. This approach moves the C language at compile time to the runtime, which gives you extra flexibility.
There is a @selector in Objective-c, which is translated into "choice" in many places. In fact, for an instance object of a class, the method of the class is represented by a number, not a long string of strings that we see with this character. This @selector can be used to turn the name of the method into the corresponding number. When a class is determined, the @selector value of each method is actually fixed, and here you can think of what method swizzling is, yes, if we had a method, @selector (a) is a number, After receiving a message, our object looks for the corresponding method and runs it--if we replace the number of @selector (B) with the original @selector (a), then the object will run the B method if it receives a message.
In iOS, this is perfectly achievable, so when do we need to do this? I think there are 2 of times:
1. Crack, needless, this is definitely a weapon to crack, do not explain.
2. During the development and debugging process, if you are unsure of the method in a library or feel the need to expand, you can write one yourself to replace it. Because Objective-c is a category, it is not necessary to extend the function, but it is convenient and practical to add some print statements when debugging.
For example, nsstring inside of the lowercasestring method, if I am not quite sure what this method has done, I can write a method to replace it, this method to add a print statement, so that the log inside a glance.
First, you need to add a nsstring category
@interface NSString (wztest)-(nsstring*) mylowerstring; @end @implementation NSString (wztest)-(nsstring*) mylowerstring{ NSString *lowerstring = [self mylowerstring]; NSLog (@ "%@ =%@", self, lowerstring); return lowerstring;} @end
Here's a place to explain that, in the Mylowerstring method, it looks like a recursive call to itself. However, we will use the original lowercasestring method to replace the Mylowerstring method that we wrote, so this does not call itself, but instead calls the original LowerCaseString method . Please pay attention to this point.
second, replace the system with the original lowercasestring method, use the method inside the runtime.
Method Originalmethod = Class_getinstancemethod ([NSString class], @selector (lowercasestring)); Method Swapmethod = Class_getinstancemethod ([NSString class], @selector (mylowerstring)); Method_exchangeimplementations (Originalmethod, swapmethod); NSString *teststr = @ "This is the Test STRING"; NSLog (@ "lowerstring of teststr=%@", [Teststr lowercasestring]);
let's look at the results of log:
2014-05-29 22:17:55.514 testtableview[1582:a0b] This is the test string = This is the test string
2014-05-29 22:17:55.514 testtableview[1582:a0b] lowerstring of Teststr=this is the test string
As we can see, the use of the system is to continue to use the lowercasestring method, but the actual implementation is our new method. When you do not need to do this, close method swizzling can be restored.
In our example, we have added a print statement, and we can actually do more with it. This is useful when debugging with a third-party library, so it's easy to see the contents of variables or do some other work. After debugging, Close method swizzling can work normally.