把runtime的内容由浅入深分几篇博客记录下来,希望能与大家共同探讨。
1,消息传递:messaging
可以看苹果定义的一些相关结构体,从而了解方法调用的内部原理。(越来越觉得还是看英文顺眼~)
objc/objc.h
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;
#endif
/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;
/// A pointer to the function of a method implementation.
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
struct objc_method {
SEL method_name OBJC2_UNAVAILABLE;
char *method_types OBJC2_UNAVAILABLE;
IMP method_imp OBJC2_UNAVAILABLE;
}
struct objc_method_list {
struct objc_method_list *obsolete OBJC2_UNAVAILABLE;
int method_count OBJC2_UNAVAILABLE;
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
/* variable length structure */
struct objc_method method_list[1] OBJC2_UNAVAILABLE;
}
#import <Foundation/Foundation.h>
@interface RuntimeObject : NSObject
//- (void)runtimeTest;
@end
.m#import "RuntimeObject.h"
#import <objc/runtime.h>
#import <objc/message.h>
@implementation RuntimeObject
//添加了一个c函数
void addedTheRuntimeTestMethod(id obj, SEL _cmd) {
NSLog(@"addedTheRuntimeTestMethod execute !");
}
+ (BOOL)resolveInstanceMethod:(SEL)sel{
if (sel == @selector(runtimeTest)) {
//可以重写父类的方法,但是本类的方法如果想改变IMP,使用method_setImplementation
class_addMethod([self class], sel, (IMP)addedTheRuntimeTestMethod, "v@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
@end
调用方式:
RuntimeObject *object = [[RuntimeObject alloc]init];
// [object runtimeTest];
[object performSelector:@selector(runtimeTest)];
运行结果:
2015-04-04 23:32:14.811 Test_4_4[2787:1225177] addedTheRuntimeTestMethod execute !
可见我们用runtime添加的方法执行了。
今天就到这里吧,更多精彩,最近会继续~