美文网首页
runtime(一)

runtime(一)

作者: 洱舟 | 来源:发表于2019-01-17 17:58 被阅读9次

总结:
Class

get 类名,父类;实例变量;属性;实例方法,类方法,方法实现;

Copy 实例变量列表;属性列表;协议列表;方法列表

Add 实例变量,属性,协议,方法

replace 方法;属性

responds 响应方法

conforms 实现协议

Objc

get 类,实例变量,实例变量的值,元类,协议,关联对象,类列表

copy 类列表,协议列表

set 实例变量,类,实例变量的值

一、runtime 文档

源码github: objc-runtime

官方API: Objective-C Runtime

二、类的本质

1、对象:含有 isa指针的结构体

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class. 表示类的实例
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.指向类实例的指针
typedef struct objc_object *id;

2、类:Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。

#import "objc/runtime.h" 查看runtime.h中 objc_class结构体实现
struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
    
#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE; //父类
    const char * _Nonnull name                               OBJC2_UNAVAILABLE; //类名
    long version                                             OBJC2_UNAVAILABLE; //类的版本信息
    long info                                                OBJC2_UNAVAILABLE; //类信息,供运行期使用的一些位标识
    long instance_size                                       OBJC2_UNAVAILABLE; //类的实例变量大小
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE; //类的实例变量列表
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;   //方法链表
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE; //方法缓存
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE; //协议链表
#endif
image

向一个Objective-C对象发送消息时,运行时库会根据实例对象的isa指针找到这个实例对象所属的类。Runtime库会在类的方法列表由super_class指针找到父类的方法列表直至根类NSObject中去寻找与消息对应的selector指向的方法。找到后即运行这个方法

1、 isa:实例对象->类->元类->(`不经过父元类`)直接到根元类(NSObject的元类),`根元类的isa指向自己`;

2、 superclass:类->父类->...->根类NSObject,`元类->父元类->...->根元类->根类`,NSObject的superclass指向nil。

三、方法

一、Class

1、get 类名,父类;实例变量;属性;实例方法,类方法,方法实现;

//类名
OBJC_EXPORT const char * _Nonnull
class_getName(Class _Nullable cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//父类
OBJC_EXPORT Class _Nullable
class_getSuperclass(Class _Nullable cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//类定义的版本号
OBJC_EXPORT int
class_getVersion(Class _Nullable cls)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//类实现大小
OBJC_EXPORT size_t
class_getInstanceSize(Class _Nullable cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//类的实例变量的信息
OBJC_EXPORT Ivar _Nullable
class_getClassVariable(Class _Nullable cls, const char * _Nonnull name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//类的实例对象方法
OBJC_EXPORT Method _Nullable
class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//类实例对象的实例变量的信息
OBJC_EXPORT Ivar _Nullable
class_getInstanceVariable(Class _Nullable cls, const char * _Nonnull name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//类方法
OBJC_EXPORT Method _Nullable
class_getClassMethod(Class _Nullable cls, SEL _Nonnull name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//获取的方法实现
OBJC_EXPORT IMP _Nullable
class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//获取指定的属性
OBJC_EXPORT objc_property_t _Nullable
class_getProperty(Class _Nullable cls, const char * _Nonnull name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//源自于类的动态库名称
OBJC_EXPORT const char * _Nullable
class_getImageName(Class _Nullable cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

2、copy 实例变量列表,方法列表,协议列表,属性列表

//实例变量列表
OBJC_EXPORT Ivar _Nonnull * _Nullable
class_copyIvarList(Class _Nullable cls, unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//方法列表
OBJC_EXPORT Method _Nonnull * _Nullable
class_copyMethodList(Class _Nullable cls, unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//协议列表
OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable
class_copyProtocolList(Class _Nullable cls, unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//属性列表
OBJC_EXPORT objc_property_t _Nonnull * _Nullable
class_copyPropertyList(Class _Nullable cls, unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

3、add 实例变量、属性、方法、协议

//增加方法
OBJC_EXPORT BOOL
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,
                const char * _Nullable types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//增加实例变量
OBJC_EXPORT BOOL
class_addIvar(Class _Nullable cls, const char * _Nonnull name, size_t size,
              uint8_t alignment, const char * _Nullable types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//增加协议
OBJC_EXPORT BOOL
class_addProtocol(Class _Nullable cls, Protocol * _Nonnull protocol)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//增加属性
OBJC_EXPORT BOOL
class_addProperty(Class _Nullable cls, const char * _Nonnull name,
                  const objc_property_attribute_t * _Nullable attributes,
                  unsigned int attributeCount)
OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

4、replace 属性、方法

//替换属性
OBJC_EXPORT void
class_replaceProperty(Class _Nullable cls, const char * _Nonnull name,
                      const objc_property_attribute_t * _Nullable attributes,
                      unsigned int attributeCount)
OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

//替换方法
OBJC_EXPORT IMP _Nullable
class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,
                    const char * _Nullable types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

5、responds 方法

//类实例是否响应指定的selector,返回BOOL值
OBJC_EXPORT BOOL
class_respondsToSelector(Class _Nullable cls, SEL _Nonnull sel) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

6、conforms 协议

//判断是否实现协议,返回一个BOOL值
OBJC_EXPORT BOOL
class_conformsToProtocol(Class _Nullable cls, Protocol * _Nullable protocol) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
二、objc

1、get 类,实例变量,实例变量的值,元类,协议,关联对象,类列表

//返回指定类
OBJC_EXPORT Class _Nullable
objc_getClass(const char * _Nonnull name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//返回指定类的元类
OBJC_EXPORT Class _Nullable
objc_getMetaClass(const char * _Nonnull name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//获取已注册的类定义列表
OBJC_EXPORT int
objc_getClassList(Class _Nonnull * _Nullable buffer, int bufferCount)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//协议
OBJC_EXPORT Protocol * _Nullable
objc_getProtocol(const char * _Nonnull name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//关联对象
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);

//获取对象中实例变量的值
OBJC_EXPORT id _Nullable
object_getIvar(id _Nullable obj, Ivar _Nonnull ivar)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//获取类实例的实例变量的值
OBJC_EXPORT Ivar _Nullable
object_getInstanceVariable(id _Nullable obj, const char * _Nonnull name,
                           void * _Nullable * _Nullable outValue)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
OBJC_ARC_UNAVAILABLE;

//返回对象的类
OBJC_EXPORT Class _Nullable
object_getClass(id _Nullable obj)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

2、copy 类列表,协议列表

//类列表
OBJC_EXPORT Class _Nonnull * _Nullable
objc_copyClassList(unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0, 2.0);

//协议列表
OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable
objc_copyProtocolList(unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

3、set 实例变量,类,实例变量的值

//设置实例变量
OBJC_EXPORT void
object_setIvar(id _Nullable obj, Ivar _Nonnull ivar, id _Nullable value)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//设置对象中实例变量的值
OBJC_EXPORT void
object_setIvarWithStrongDefault(id _Nullable obj, Ivar _Nonnull ivar,
                                id _Nullable value)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);

//改变类实例的实例变量的值
OBJC_EXPORT Ivar _Nullable
object_setInstanceVariable(id _Nullable obj, const char * _Nonnull name,
                           void * _Nullable value)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
OBJC_ARC_UNAVAILABLE;

//设置对象的类
OBJC_EXPORT Class _Nullable
object_setClass(id _Nullable obj, Class _Nonnull cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

4、dispose

//释放给定对象的内存
OBJC_EXPORT id _Nullable
object_dispose(id _Nullable obj)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;

5、创建类、销毁类

//创建一个类或者元类
OBJC_EXPORT Class _Nullable
objc_allocateClassPair(Class _Nullable superclass, const char * _Nonnull name, 
                       size_t extraBytes) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//销毁一个类或者元类
OBJC_EXPORT void
objc_disposeClassPair(Class _Nonnull cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
// 在应用中注册由objc_allocateClassPair创建的类
void objc_registerClassPair ( Class cls );

6、创建、销毁对象

//创建对象
OBJC_EXPORT id _Nullable
class_createInstance(Class _Nullable cls, size_t extraBytes)
    OBJC_RETURNS_RETAINED
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//销毁
OBJC_EXPORT void * _Nullable objc_destructInstance(id _Nullable obj) 
    OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;
三、数据类型
struct objc_ivar {
    char * _Nullable ivar_name                               OBJC2_UNAVAILABLE;
    char * _Nullable ivar_type                               OBJC2_UNAVAILABLE;
    int ivar_offset                                          OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
}

1、ivar_get

//获取实例变量名称
OBJC_EXPORT const char * _Nullable
ivar_getName(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回实例变量类型字符串
OBJC_EXPORT const char * _Nullable
ivar_getTypeEncoding(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

//返回实例变量的偏移量
OBJC_EXPORT ptrdiff_t
ivar_getOffset(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

2、property_get

//获取属性名称
OBJC_EXPORT const char * _Nonnull
property_getName(objc_property_t _Nonnull property) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回属性的属性字符串
OBJC_EXPORT const char * _Nullable
property_getAttributes(objc_property_t _Nonnull property) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回属性的属性属性数组
OBJC_EXPORT objc_property_attribute_t * _Nullable
property_copyAttributeList(objc_property_t _Nonnull property,
                           unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);
四、函数
struct objc_method {
    SEL _Nonnull method_name                                 OBJC2_UNAVAILABLE;
    char * _Nullable method_types                            OBJC2_UNAVAILABLE;
    IMP _Nonnull method_imp                                  OBJC2_UNAVAILABLE;
}
  • SEL _Nonnull method_name 选择器,表示一个方法的selector的指针,映射方法的名字
  • char *method_types 方法类型
  • IMP _Nonnull method_imp 方法实现

1、method_get

//获得方法名
OBJC_EXPORT SEL _Nonnull
method_getName(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//获得方法的实现
OBJC_EXPORT IMP _Nonnull
method_getImplementation(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回描述方法参数和返回类型的字符串
OBJC_EXPORT const char * _Nullable
method_getTypeEncoding(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回方法接受的参数个数
OBJC_EXPORT unsigned int
method_getNumberOfArguments(Method _Nonnull m)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

2、method_copy

//获取方法返回值类型字符串
OBJC_EXPORT char * _Nonnull
method_copyReturnType(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回方法单个参数类型的字符串
OBJC_EXPORT char * _Nullable
method_copyArgumentType(Method _Nonnull m, unsigned int index) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

3、method_set

//设置方法的实现
OBJC_EXPORT IMP _Nonnull
method_setImplementation(Method _Nonnull m, IMP _Nonnull imp) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

4、method_exchangeImplementations

//交换两个方法
OBJC_EXPORT void
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

5、sel_

//返回指定选择器的方法名称
OBJC_EXPORT const char * _Nonnull
sel_getName(SEL _Nonnull sel)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
    
//使用Objective-C运行时系统注册方法,映射方法 *命名为选择器,并返回选择器值。  
OBJC_EXPORT SEL _Nonnull
sel_registerName(const char * _Nonnull str)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

//比较两个选择器
OBJC_EXPORT BOOL
sel_isEqual(SEL _Nonnull lhs, SEL _Nonnull rhs) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
五、协议
//判断一个协议是否符合另一个协议,返回BOOL
OBJC_EXPORT BOOL
protocol_conformsToProtocol(Protocol * _Nullable proto,
                            Protocol * _Nullable other)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//协议比较两个协议是否相等
OBJC_EXPORT BOOL
protocol_isEqual(Protocol * _Nullable proto, Protocol * _Nullable other)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//获取协议名称
OBJC_EXPORT const char * _Nonnull
protocol_getName(Protocol * _Nonnull proto)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//获取协议的属性
OBJC_EXPORT objc_property_t _Nullable
protocol_getProperty(Protocol * _Nonnull proto,
                     const char * _Nonnull name,
                     BOOL isRequiredProperty, BOOL isInstanceProperty)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//返回协议属性列表
OBJC_EXPORT objc_property_t _Nonnull * _Nullable
protocol_copyPropertyList(Protocol * _Nonnull proto,
                          unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//协议采用的协议列表
OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable
protocol_copyProtocolList(Protocol * _Nonnull proto,
                          unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
    
//向协议中增加方法
OBJC_EXPORT void
protocol_addMethodDescription(Protocol * _Nonnull proto, SEL _Nonnull name,
                              const char * _Nullable types,
                              BOOL isRequiredMethod, BOOL isInstanceMethod) 
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);
    
//协议中增加属性
OBJC_EXPORT void
protocol_addProperty(Protocol * _Nonnull proto, const char * _Nonnull name,
                     const objc_property_attribute_t * _Nullable attributes,
                     unsigned int attributeCount,
                     BOOL isRequiredProperty, BOOL isInstanceProperty)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);
    
//指示一个协议是否遵守另一个协议。返回值BOOL
OBJC_EXPORT BOOL
protocol_conformsToProtocol(Protocol * _Nullable proto,
                            Protocol * _Nullable other)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
六、消息发送和消息转发
1、消息发送:方法调用称为向对象发送消息
id objc_msgSend(id self, SEL op, ...);

self:消息的接收者 op: 消息的方法名,C 字符串... :参数列表

2、消息转发

1、动态方法解析

//类
+ (BOOL)resolveClassMethod:(SEL)name;
//对象
+ (BOOL)resolveInstanceMethod:(SEL)name

//根据方法调用者类型,从其中二选一

2、备援接收者:动态方法解析没有实现或者无法处理的时候,就会执行;,如果咩有备援接收者,返回nil

- (id)forwardingTargetForSelector:(SEL)aSelector;

3、消息转发

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;

- (void)forwardInvocation: (NSInvocation*)invocation;

具体代码实现:

在没有实现方法的前提下,去调用方法,才会触发消息转发。否则不会

[self performSelector:@selector(clickButtonHub) withObject:self afterDelay:0.3];


void dynamicAdditionMethodIMP(id self, SEL _cmd) {
    NSLog(@"dynamicAdditionMethodIMP");
}

+ (BOOL)resolveInstanceMethod:(SEL)name {
    NSLog(@"动态方法解析");
    
    //判断没有实现方法, 那么我们就是动态添加一个方法
    if (name == @selector(clickButtonHub)) {
        class_addMethod([self class], name, (IMP)dynamicAdditionMethodIMP, "v@:");
        return YES;
    }
    return [super resolveInstanceMethod:name];
}

//消息备援接收者
- (id)forwardingTargetForSelector:(SEL)aSelector{
    NSLog(@"消息备援接收者");
    return [super forwardingTargetForSelector:aSelector];
}

//消息重新定向
- (void)forwardInvocation: (NSInvocation*)invocation{
    NSLog(@"消息重新定向1");
    [super forwardInvocation:invocation];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    NSLog(@"消息重新定向2");
    
   return [super methodSignatureForSelector:aSelector];
}

//打印
2019-01-17 17:34:57.514365+0800 Demo[3174:1499686] 动态方法解析
2019-01-17 17:34:57.514504+0800 Demo[3174:1499686] dynamicAdditionMethodIMP


注释掉动态方法里面这段代码
/*
    if (name == @selector(clickButtonHub)) {
        class_addMethod([self class], name, (IMP)dynamicAdditionMethodIMP, "v@:");
        return YES;
    }
*/

//打印
2019-01-17 17:40:21.169707+0800 Demo[3280:1520341] 动态方法解析
2019-01-17 17:40:21.169854+0800 Demo[3280:1520341] 消息备援接收者
2019-01-17 17:40:21.170009+0800 Demo[3280:1520341] 消息重新定向2

生成方法签名转发消息

[self performSelector:@selector(clickButtonHub) withObject:self afterDelay:0.3];

+ (BOOL)resolveInstanceMethod:(SEL)name {
    NSLog(@"动态方法解析");
    return [super resolveInstanceMethod:name];
}

- (id)forwardingTargetForSelector:(SEL)aSelector{
    NSLog(@"消息备援接收者");
    return [super forwardingTargetForSelector:aSelector];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    NSLog(@"消息重新定向2");
    
    //转化字符
    NSString *sel = NSStringFromSelector(aSelector);
    //判断, 手动生成签名
    if([sel isEqualToString:@"clickButtonHub"]){
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
    }else{
        return [super methodSignatureForSelector:aSelector];
    }
}

//消息重新定向
- (void)forwardInvocation: (NSInvocation*)invocation{
    NSLog(@"消息重新定向1");
    
    //取得消息
    SEL selector = [invocation selector];
    //转发
    ClassStudentModel *model = [[ClassStudentModel alloc]init];
    if ([model respondsToSelector:selector]) {
        //调用对象,进行转发
        [invocation invokeWithTarget:model];
    }else{
        [super forwardInvocation:invocation];
    }
}

//ClassStudentModel.h 中
@interface ClassStudentModel : NSObject
- (void)clickButtonHub;
@end

//ClassStudentModel.m

@implementation ClassStudentModel
- (void)clickButtonHub{
    NSLog(@"ClassStudentModel---clickButtonHub");
}

//打印结果
2019-01-17 17:49:51.947708+0800 Demo[3564:1558162] 动态方法解析
2019-01-17 17:49:51.947831+0800 Demo[3564:1558162] 消息备援接收者
2019-01-17 17:49:51.947925+0800 Demo[3564:1558162] 消息重新定向2
2019-01-17 17:49:51.948028+0800 Demo[3564:1558162] 动态方法解析
2019-01-17 17:49:51.948115+0800 Demo[3564:1558162] 消息重新定向1
2019-01-17 17:49:51.948211+0800 Demo[3564:1558162] ClassStudentModel---clickButtonHub

@end

相关文章

网友评论

      本文标题:runtime(一)

      本文链接:https://www.haomeiwen.com/subject/uqxwdqtx.html