總結:
Classget 類名,父類;實例變量;屬性;實例方法,類方法,方法實現;
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
向一個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