OC的类信息存放在哪里,看完千万别说还不知道

简介: 这篇行文主要介绍OC的类信息具体存放在哪个位置。在了解这个之前,要先明白 Objective-C中的对象(后称OC对象),主要可以分为哪几种,如下:1、instance对象(实例对象)2、class对象(类对象)-https://so.csdn.net/so/search?q=%E7%B1%BB%E5%AF%B9%E8%B1%A1&spm=1001.2101.3001.70203、meta-class对象(元类对象)

一、instance对象(实例对象)


instance 对象:就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象。


示例一:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *object1 = [[NSObject alloc] init];
        NSObject *object2 = [[NSObject alloc] init];
        NSLog(@"%p %p",
              object1,
              object2);
    }
    return 0;
}


object1、object2 是 NSObject 的 instance 对象(实例对象)。

它们是不同的两个对象,分别占据着两块不同的内存。


示例二:03797e4de39d4c228faf6b61aef4e3bd.png


结构分析:

5d3abe1d5e254de18ae79a33c3096869.png


instance对象在内存中存储的信息包括:


isa指针

其他成员变量


二、class对象(类对象)


#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *object1 = [[NSObject alloc] init];
        NSObject *object2 = [[NSObject alloc] init];
        Class objectClass1 = [object1 class];
        Class objectClass2 = [object2 class];
        Class objectClass3 = object_getClass(object1);
        Class objectClass4 = object_getClass(object2);
        Class objectClass5 = [NSObject class];
        NSLog(@"%p %p",
              object1,
              object2);
        NSLog(@"%p %p %p %p %p",
              objectClass1,
              objectClass2,
              objectClass3,
              objectClass4,
              objectClass5);
    }
    return 0;
}


objectClass1 ~ objectClass5都是NSObject的class对象(类对象)

它们是同一个对象。每个类在内存中有且只有一个class对象。


class对象在内存中存储的信息主要包括:


isa指针

superclass指针

类的属性信息(@property)

类的对象方法信息(instance method)

类的协议信息(protocol)

类的成员变量信息(ivar)


三、meta-class对象(元类对象)


Class objectMetaClass = object_getClass([NSObject class]);
NSObject *object1 = [[NSObject alloc] init];
Class objectClass1 = [object1 class];
Class objectMetaClass = object_getClass(objectClass1);


objectMetaClass是NSObject的meta-class对象(元类对象)

每个类在内存中有且只有一个meta-class对象


注意:meta-class对象和class对象的内存结构是一样的,但是用途不一样。


在内存中存储的信息主要包括:


isa指针

superclass指针

类的类方法信息(class method)


四、总结


#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // instance对象,实例对象
        NSObject *object1 = [[NSObject alloc] init];
        NSObject *object2 = [[NSObject alloc] init];
        // class对象,类对象
        Class objectClass1 = [object1 class];
        Class objectClass2 = [object2 class];
        Class objectClass3 = object_getClass(object1);
        Class objectClass4 = object_getClass(object2);
        Class objectClass5 = [NSObject class];
        // class方法返回的一直是class对象,类对象
       // Class objectMetaClass2 = [[[NSObject class] class] class];
        // meta-class对象,元类对象
        // 将类对象当做参数传入,获得元类对象
        Class objectMetaClass = object_getClass(objectClass5);
        NSLog(@"instance - %p %p",
              object1,
              object2);
        NSLog(@"class - %p %p %p %p %p %d",
              objectClass1,
              objectClass2,
              objectClass3,
              objectClass4,
              objectClass5,
              class_isMetaClass(objectClass3));
        NSLog(@"objectMetaClass - %p %d", objectMetaClass, class_isMetaClass(objectMetaClass));
    }
    return 0;
}


拓展:


1、Class objc_getClass(const char *aClassName)


1> 传入字符串类名

2> 返回对应的类对象


2、Class object_getClass(id obj)


1> 传入的obj可能是instance对象、class对象、meta-class对象

2> 返回值

a) 如果是instance对象,返回class对象

b) 如果是class对象,返回meta-class对象

c) 如果是meta-class对象,返回NSObject(基类)的meta-class对象


3、- (Class)class、+ (Class)class


1> 返回的就是类对象


- (Class) {
    return self->isa;
}
+ (Class) {
    return self;
}


4、OC的类信息存放在哪里?


1、对象方法、属性、成员变量、协议信息,存放在class对象中。

2、类方法,存放在meta-class对象中。

3、成员变量的具体值,存放在instance对象。


相关文章
|
7月前
|
Java
在 Java 中,类是一种定义对象的模板,它包含数据成员(字段)和方法。
在 Java 中,类是一种定义对象的模板,它包含数据成员(字段)和方法。
|
7月前
|
Java Apache
Java将一个对象的属性复制到另一个对象,如何编码
【6月更文挑战第15天】Java将一个对象的属性复制到另一个对象,如何编码
404 3
|
存储 编译器 C语言
[C++ 提高] --- 类的存储 和 包含虚函数的类
[C++ 提高] --- 类的存储 和 包含虚函数的类
76 0
[C++ 提高] --- 类的存储 和 包含虚函数的类
拷贝实体的工具类---BeanObjectCopyUtils
拷贝实体的工具类---BeanObjectCopyUtils
146 0
|
架构师 Java
[Java Base] 类,接口,枚举,静态常量到底应该放在哪?
静态常量什么时候适合放在类中?什么时候适合放在接口中?什么时候适合放在枚举中呢?放在不同的type中会引发什么不良后果呢?本篇就来解析一下~常量类应该是final,不变的,而接口里的参数是final,也是不变的。那么,看起来接口是放常量没有一定问题,还省去了final的输入,非常的合适。但是,类是只能单继承的,接口是允许多实现的。要是类实现的多个接口出现重名的常量,会报错,必须要在实现类明确常量用的是哪个接口的。
280 0
|
Go
Go基础:路径、文件名和包名的关系
Go基础:路径、文件名和包名的关系
773 0
Go基础:路径、文件名和包名的关系
|
存储 Java 编译器
JVM14_Class文件结构细节、魔数、Class文件版本、常量池、访问标识(或标志)、类索引|父类索引|接口索引集合、字段|方法|属性表集合(二)
③. 如何确保高版本的JVM可执行低版本的class文件? ④. 常量池(class文件的基石) ①. 什么是常量池? ②. 常量池计数器 ③. 常量池表
141 0
JVM14_Class文件结构细节、魔数、Class文件版本、常量池、访问标识(或标志)、类索引|父类索引|接口索引集合、字段|方法|属性表集合(二)
|
索引
JVM14_Class文件结构细节、魔数、Class文件版本、常量池、访问标识(或标志)、类索引|父类索引|接口索引集合、字段|方法|属性表集合(七)
⑩. IDEA中集成jclasslib说明Class文件信息 ①. Class文件详解 ②. 方法表集合 ③. code属性 ④. LineNumberTable、LocalVariableTable ④. SourceFile属性
113 0
JVM14_Class文件结构细节、魔数、Class文件版本、常量池、访问标识(或标志)、类索引|父类索引|接口索引集合、字段|方法|属性表集合(七)