理解objc运行时一:类是什么

环境说明

macOS Sierra 10.12.1
Xcode 8.1

获得可运行的objc源码

一个可以编译并运行的objc源码才能更好的理解运行时
objc-706

OC中的大部分类是继承自NSObject这个类的
因此从NSObject这个类入手

NSObject.h

1
2
3
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}

可知NSObject对象包含一个Class类型的isa指针

Class

有3个文件与Class有关

打开一个其他的一个正常的Xcode工程,同样点击Class

进入到 objc.h

再进入到runtime.h,Class的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/* Types */

#if !OBJC_TYPES_DEFINED

/// An opaque type that represents a method in a class definition.
typedef struct objc_method *Method;

/// An opaque type that represents an instance variable.
typedef struct objc_ivar *Ivar;

/// An opaque type that represents a category.
typedef struct objc_category *Category;

/// An opaque type that represents an Objective-C declared property.
typedef struct objc_property *objc_property_t;

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;
/* Use `Class` instead of `struct objc_class *` */

#endif

注意有个#if !OBJC_TYPES_DEFINED宏定义,正常Xcode工程找不到定义,但在objc-706工程中搜索可得,它在objc-private.h中,#define OBJC_TYPES_DEFINED 1所以上面的代码其实是不会参与编译的,真正的定义在在objc-private.h,再进入到objc-runtime-old.h,但是还有一个objc-runtime-new.h,根据命名与调试结果,真正的定义是objc-runtime-new.h

1
2
3
4
5
6
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
...
1
typedef struct objc_class *Class;*

Class是一个指向objc_class结构体的指针

参考