Use the Runtime method in combination with the dynamic addition of instances.

Source: Internet
Author: User

Use the Runtime method in combination with the dynamic addition of instances.

Method substitution can replace any external class method. Dynamic addition can only be implemented in the object created by the added class, but can be used in combination with dynamic addition, it can be implemented by dynamically adding the required methods to any external class. This method can be a class method or an instance method. This external class can also be a class without any method declaration or implementation.

Main Idea: Use the runtime method to replace the custom method in the external classhy_resolveInstanceMethodOrhy_resolveClassMethod(Usehy_Prefix indicates my custom method) andresolveInstanceMethodOrresolveClassMethodMethod replacement.hy_resolveInstanceMethodOrhy_resolveClassMethodThe method should be written inresolveInstanceMethodOrresolveClassMethodThe logic of the dynamic addition method of runtime written in the method.

It's a bit difficult, but at least you need to read the source code and think about the logic. The premise is that you are familiar with the runtime method.

Defects: 1. It is difficult to process methods with parameters. The parameter values must be determined based on the actual business logic.

Before use import <objc/message.h>, Need following:

Create Person. h and Person. m

Person. h:

1 #import <Foundation/Foundation.h>2 3 @interface Person : NSObject4 5 @end
Person. m:
1 #import "Person.h"2 3 @implementation Person4 5 @end
Create OtherPerson. h and OtherPerson. m

OtherPerson. h:

1 #import <Foundation/Foundation.h>2 3 @interface OtherPerson : NSObject4 5 6 @end

OtherPerson. m:

1 // 2 // Created by HEYANG on 16/1/11. 3 // Copyright©2016 HEYANG. all rights reserved. 4 // 5 6 # import "OtherPerson. h "7 # import <objc/message. h> 8 9 @ implementation OtherPerson10 11 12 + (void) load {13 Class clazz = NSClassFromString (@ "Person "); 14 15 // obtain the class Method before replacement 16 Method instance_eat = 17 class_getClassMethod (clazz, @ selector (resolveInstanceMethod :)); 18 // get the replaced class Method 19 Method instance_notEat = 20 class_getClassMethod (self, @ selector (handler :)); 21 22 // then switch Class Method 23 method_exchangeImplementations (instance_eat, instance_notEat); 24 25 // obtain the Class Method 26 before replacement Method class_eat = 27 class_getClassMethod (clazz, @ selector (resolveClassMethod :)); 28 // obtain the replaced class Method 29 Method class_notEat = 30 class_getClassMethod (self, @ selector (handler :)); 31 32 // then switch Class Method 33 method_exchangeImplementations (class_eat, class_notEat); 34 35} 36 37 void eat_1 (id self, SEL sel) 38 {39 NSLog (@ "Stop eating "); 40 NSLog (@ "% @", self, NSStringFromSelector (sel); 41} 42 void eat_2 (id self, SEL sel, NSString * str1, NSString * str2) 43 {44 NSLog (@ "don't eat"); 45 NSLog (@ "% @", self, NSStringFromSelector (sel )); 46 NSLog (@ "Print two parameter values: % @ and % @", str1, str2); 47} 48 49 50 + (BOOL) hy_resolveInstanceMethod :( SEL) sel {51 // when sel is in the implementation method, the eat method 52 if (sel = NSSelectorFromString (@ "eat ")) {53 // Add the eat method 54 dynamically 55 // The first parameter: Add Method 56 to the class // The second parameter: add Method number 57 // third parameter: add method function implementation (function address) 58 // fourth parameter: function type, (Return Value + parameter type) v: void @: Object-> self: SEL-> _ prop 59 class_addMethod (self, sel, (IMP) eat_1, "v @:"); 60} 61 return YES; 62} 63 + (BOOL) hy2_resolveClassMethod :( SEL) sel {64 65 if (sel = NSSelectorFromString (@ "eat: :")) {66 67 class_addMethod (objc_getMetaClass ("Person"), sel, (IMP) eat_2, "v #:@"); 68} 69 70 return YES; 71} 72 73 @ end
Last In file 'main. M ':

Main. m:

1/** 2*3 * Swap Method and Dynamic add Method (exchange Method and Dynamic addition Method) 4*5 */6 7 # import <Foundation/Foundation. h> 8 9 // ignore undeclared warm ignores undeclared warning 10 # pragma clang diagnostic push11 # pragma clang diagnostic ignored "-Wundeclared-selector" 12 13 int main (int argc, const char * argv []) {14 @ autoreleasepool {15 // get this Person class get this Person Class 16 class clazz = NSClassFromString (@ "Person "); 17 // get this Person Instance 18 id person = [[clazz alloc] init]; 19 20 // send message to 'eid' method in Person Class or Person Instance21 // The 'not' method used to send a message to the Person Class or Person instance does not include parameter 22 [person already mselector: @ selector (eat) withObject: nil]; 23 // The 'eid' Method for sending a message to the Person class contains two parameters 24 [clazz notify mselector: @ selector (eat: with :) 25 withObject: @ "Hello" 26 withObject: @ "World"]; 27} 28 return 0; 29} 30 31 # pragma clang diagnostic pop
The code test result

Extra

Download

Download github code source

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.