Objective-C中对象的分类与本质(isa&superclass)

1、OC中对象分为三种:实例对象(instance)、类对象(class)、元类对象(meta-class);
2、实例对象类型为创建该实例的类类型,类对象与元类对象均为Class类型;
3、每创建一个实例都会在内存中新创建一个实例对象,但类对象与元类对象只有一份;
4、类的成员变量值保存在实例对象中,对象方法、属性、属性类型等信息保存在类对象中,类方法保存在元类对象中;
5、所有对象都会有isa属性与superclass属性;
6、isa指针的指向为:isntance->class->meta-class;
6.1、实例对象的isa指向类对象;
6.2、类对象的isa指向元类对象;
6.3、元类对象的isa指向基类的元类对象,即OC中所有元类对象的isa都指向NSObject的元类对象;
7、superclass指向为指向相对应的父类
7.1、实例对象的superclass指向类对象的父类;
7.2、类对象的superclass指向类对象的父类,但基类类对象的superclass指向为nil;
7.3、元类对象的superclass指向元类对象的父类,但基类元类对象的superclass指向基类的类对象;
8、基本描述图示:

9、代码验证
9.1、Objective-C

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
36
37
38
39
40
41
42
43
44
45
46
//
//  ViewController.m
//  lldb
//
//  Created by 余西安 on 2018/11/1.
//  Copyright © 2018 yusian. All rights reserved.
//
 
#import "ViewController.h"
#import <objc/runtime.h>
 
@interface SAPerson : NSObject
@end
@implementation SAPerson
@end
 
@interface SAStudent : SAPerson
@end
@implementation SAStudent
@end
 
@implementation ViewController
// 为了能够使Class指针能够正常打印其isa与superclass值,自定义一个结构体用于强转输出
struct sa_object_class{
    Class isa;
    Class superclass;
};
- (void)viewDidLoad
{
    [super viewDidLoad];
    SAStudent *studentInstance = SAStudent.new;
    SAPerson *personInstance = SAPerson.new;
    NSObject *objectInstance = NSObject.new;
    NSLog(@"\nstudentInstance:%p \n,personInstance:%p \n,objectInstance:%p", studentInstance, personInstance, objectInstance);
 
    struct sa_object_class *studentClass = (__bridge struct sa_object_class *)SAStudent.class;
    struct sa_object_class *personClass = (__bridge struct sa_object_class *)SAPerson.class;
    struct sa_object_class *objectClass = (__bridge struct sa_object_class *)NSObject.class;
    NSLog(@"\nstudentClass:%p \n,personClass:%p \n,objectClass:%p", studentClass, personClass, objectClass);
 
    struct sa_object_class *studentMetaClass = (__bridge struct sa_object_class *)object_getClass(SAStudent.class);
    struct sa_object_class *personMetaClass = (__bridge struct sa_object_class *)object_getClass(SAPerson.class);
    struct sa_object_class *objectMetaClass = (__bridge struct sa_object_class *)object_getClass(NSObject.class);
    NSLog(@"\nstudentMetaClass:%p \n,personMetaClass:%p \n,objectMetaClass:%p", studentMetaClass, personMetaClass, objectMetaClass);
}
@end

9.2、LLDB调试验证

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
2018-11-10 21:30:36.278006+0800 lldb[2848:269881] 
studentInstance:0x6000018b8be0 
,personInstance:0x6000018b8940 
,objectInstance:0x6000018b8920
 
2018-11-10 21:30:36.278164+0800 lldb[2848:269881] 
studentClass:0x102481f58 
,personClass:0x102481f08 
,objectClass:0x10351df38
 
2018-11-10 21:30:36.278268+0800 lldb[2848:269881] 
studentMetaClass:0x102481f30 
,personMetaClass:0x102481ee0 
,objectMetaClass:0x10351dee8
 
 
(lldb) p/x studentInstance->isa
(Class) $0 = 0x0000000102481f58 SAStudent
(lldb) p/x personInstance->isa
(Class) $1 = 0x0000000102481f08 SAPerson
(lldb) p/x objectInstance->isa
(Class) $2 = 0x000000010351df38 NSObject
 
(lldb) p/x studentClass->isa
(Class) $3 = 0x0000000102481f30
(lldb) p/x personClass->isa
(Class) $4 = 0x0000000102481ee0
(lldb) p/x objectClass->isa
(Class) $5 = 0x000000010351dee8
 
(lldb) p/x studentMetaClass->isa
(Class) $6 = 0x000000010351dee8
(lldb) p/x personMetaClass->isa
(Class) $7 = 0x000000010351dee8
(lldb) p/x objectMetaClass->isa
(Class) $8 = 0x000000010351dee8
 
 
(lldb) p/x studentInstance.superclass
(Class) $9 = 0x0000000102481f08 SAPerson
(lldb) p/x personInstance.superclass
(Class) $10 = 0x000000010351df38 NSObject
(lldb) p/x objectInstance.superclass
(Class) $11 = nil
 
(lldb) p/x studentClass->superclass
(Class) $12 = 0x0000000102481f08 SAPerson
(lldb) p/x personClass->superclass
(Class) $13 = 0x000000010351df38 NSObject
(lldb) p/x objectClass->superclass
(Class) $15 = nil
 
(lldb) p/x studentMetaClass->superclass
(Class) $16 = 0x0000000102481ee0
(lldb) p/x personMetaClass->superclass
(Class) $17 = 0x000000010351dee8
(lldb) p/x objectMetaClass->superclass
(Class) $18 = 0x000000010351df38 NSObject

One thought on “Objective-C中对象的分类与本质(isa&superclass)

  1. Pingback: KVO的本质 | 一天到晚游泳的余

Leave a Reply