Detailed description of the call process of the Objective-C method
In Objective-C, the method is converted into a call to the message function at runtime, that is, objc_msgSend. The basic form is objc_msgSend (separator er, selector, arg1, arg2 ,...). The first parameter is the message receiver, the second parameter is a SEL-type data, and the rest are the message parameters.
If you are not clear about the basic concepts of the basic method, refer to another article. If we have a basic conceptual basis, we will analyze the process.
Defines a male human with no redundant code.
@interface Man : NSObject@end@implementation Man@end
1. If selector is a message related to memory management (such as retain, release, retainCount, etc.), it will return the receiver directly.
2. If no receiver exists, null (nil, 0, or {0}) is returned })
3. Next, the receiver will search for selector in the cached method list in the object structure. If the selector is found, the method will be called. If no result is found, search for it in all method linked lists. If no result is found, call the method and save the selector to the cached linked list. If this selector is not found in the object's struct, it will be searched in the method linked list of the parent class at the first level until NSObject stops.
These processes are similar to most languages, but Objective-C does not. It also performs more checks and operations to further save vulnerable programs.
4. Rescue Step 1: UseResolveInstanceMethod: self-help <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Expires + tq/expires + expires/a3uaOsy/nS1Lao0uXSu7j21/expires + CjxwcmUgY2xhc3M9 "brush: java;">-(NSString *) makeSomeFood :( NSString *) food; // cookingBut in Man. h, he does not implement it because he does not know whether there is meat today. If there is meat, he will cook meat and cabbage. Add the following code to Man. m:
Static id makeVegetable (id self, SEL _ cmd, id value) {NSString * intentedFood = (NSString *) value; return [NSString stringWithFormat: @ "originally intended to eat %, currently, only Chinese cabbage has been eaten ", intentedFood];}+ (BOOL)resolveInstanceMethod:(SEL)sel{ NSString *selStr = NSStringFromSelector(sel); if ([selStr isEqualToString:@"makeSomeFood:"]) { class_addMethod([Man class], sel, (IMP)makeVegetable, "v@:@"); } return [super resolveInstanceMethod:sel];}
ResolveInstanceMethod: first judge the method name in the method. If it is makeSomeFood: method, dynamically Add a makeVegetable method at runtime to process the method and return the result. The first parameter of class_addMethod is the class name, the second parameter is the method name, the third is the function implementation address, and the fourth parameter is the type encoding parameter.5. Save Step 2: UseForwardingTargetForSelector: For Help --- backup recipient
If a man wants to have a child, he must ask for help from his wife. Of course, the premise is that he is willing to have a child for him.
Define the Wife class
@ Interface Wife: NSObject @ end @ implementation Wife-(void) giveBirthToBaby {NSLog (@ "");} @ end
// Add method in Man. h@ Property (nonatomic, retain) Wife * mWife;-(void) giveBirthToBaby; // give birth
// Implementation in Man. m- (id)forwardingTargetForSelector:(SEL)aSelector{ if ([_mWife respondsToSelector:aSelector]) { return _mWife; } return [super forwardingTargetForSelector:aSelector];}
// During initializationMan *people = [[Man alloc] init];people.mWife = Wife.new;[people giveBirthToBaby];
When you call giveBirthToBaby:, you will perform the fourth step to check whether you can solve the problem on your own. When the problem cannot be solved, _ mWife will implement the corresponding method, on the surface, Man implements this method.
Note that because the new object is allowed to execute this method, a necessary process is also required if the new object has no implementation method, the implementation method will be found in the parent class. If the method is found, it will be called and stored in the cache linked list. If the method is not found, an exception will be thrown, and the next rescue method will continue.
6. Save Step 3: Use forwardInVocation: Outsourcing --- complete message forwardingSuppose this man wants to create a large plane now. Although he is a local tyrant, he can only outsource it to his friends.
Define the class of friends who can solve the problem:
@ Interface RichFriend: NSObject @ end @ implementation RichFriend-(void) makeSomeAirplane :( NSString *) airPlaine {NSLog (@ "% @", [NSString stringWithFormat: @ "manufacturing % @ successful", airPlaine]);} @ end
// Add method-(void) makeSomeAirplane :( NSString *) airPlaine in Man. h; // create an airplane
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ NSMethodSignature *sig = [super methodSignatureForSelector:aSelector]; if (!sig) { if ([RichFriend instancesRespondToSelector:aSelector]) { sig = [RichFriend instanceMethodSignatureForSelector:aSelector]; } } return sig;}- (void)forwardInvocation:(NSInvocation *)anInvocation{ if ([RichFriend instancesRespondToSelector:anInvocation.selector]) { [anInvocation invokeWithTarget:RichFriend.new]; } else { [super forwardInvocation:anInvocation]; }}
// Initialize Man * people = [[Man alloc] init]; [people makeSomeAirplane: @ "A380"];
If neither part 4 nor 5 can solve the problem, NSInVocation can only be performed in the last step for forwarding. NSInvocation is an encapsulation class containing aggreger, selector, parameter, etc, package all relevant information. First, you need to use methodSignatureForSelector: method to obtain the selector method signature and create an NSInvocation object. This object can use the invokeWithTarget: Method to drive new recipients to process messages.If no message is processed in this step, NSObject's forwardInVocation will call doesNotRecognizeSelector: method, and the program will crash.
Finally: