NSObject为全部类的根类,它位于整个类层次的根上,类层次中的全部其它类最终都是从根类继承而来。(万物皆NSObject)bash
咱们知道全部的类均可以用class接收,因此咱们建立一个类对象app
Person *person = [Person alloc];
Class pClass = object_getClass(person);
复制代码
查看Class源码:ui
typedef struct objc_class *Class;
复制代码
查看objc_class源码:this
struct objc_class : objc_object {
// Class ISA;
Class superclass; //
cache_t cache; // formerly cache pointer and vtable
class_data_bits_t bits; // class_rw_t * plus custom rr/alloc flags
// 下面是一些方法
class_rw_t *data() {
return bits.data();
}
…
}
复制代码
objc_class中的Class ISA属性继承自父类 objc_object,查看objc_object源码:atom
struct objc_object {
private:
isa_t isa;
…
}
复制代码
???、objc_object与NSObject有什么关系呢? 咱们再来看NSObject的源码定义:spa
NSObject的源码定义:
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
Class isa OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}
复制代码
其实他们是同一个事物的不一样表现形式。objc_object为c结构体写法,而NSObject为OC写法。3d
咱们为类对象添加成员变量、属性和实例方法、类方法:调试
@interface Person : NSObject{
NSString *hobby;
}
@property (nonatomic, copy) NSString *nickName;
- (void)sayHello;
+ (void)sayHappy;
@end
复制代码
首先咱们查看objc_class源码中的方法:code
class_rw_t *data() {
return bits.data();
}
复制代码
查看class_rw_t,surprise:orm
struct class_rw_t {
// Be warned that Symbolication knows the layout of this structure.
uint32_t flags;
uint32_t version;
//———————————重点—————————————
const class_ro_t *ro;
method_array_t methods;
property_array_t properties;
protocol_array_t protocols;
//——————————————————————————
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
#if SUPPORT_INDEXED_ISA
uint32_t index;
#endif
…
};
复制代码
因此咱们要找的东西就在这个class_rw_t里面。
接下来咱们开始lldb调试:
Class ISA(8个字节)+ Class superclass(8个字节)+ cache_t cache(?)
仍是查看源码:
typedef uint32_t mask_t; // 4
struct cache_t {
struct bucket_t *_buckets; // 8
mask_t _mask; // 4
mask_t _occupied; // 4
…
}
复制代码
得出: Class ISA(8个字节)+ Class superclass(8个字节)+ cache_t cache(16个字节),即偏移0x20个字节。
实例方法一样存在于baseMethodList中
咱们会发现,在class_data_bits_t里面,是不管如何都找不到类方法的,怎么办呢?咱们只能去它的元类里面查看。定义一个方法:
void testInstanceMethod_classToMetaclass(Class pClass){
const char *className = class_getName(pClass);
Class metaClass = objc_getMetaClass(className);
Method method1 = class_getInstanceMethod(pClass, @selector(sayHello));
Method method2 = class_getInstanceMethod(metaClass, @selector(sayHello));
Method method3 = class_getInstanceMethod(pClass, @selector(sayByeBye));
Method method4 = class_getInstanceMethod(metaClass, @selector(sayByeBye));
NSLog(@"%p-%p-%p-%p",method1,method2,method3,method4);
}
复制代码
打印结果:
0x100002248-0x0-0x0-0x1000021e0
印证了咱们的想法,类方法确实存在于它的元类里面。