1.OC 对象本质是结构体
#import <Foundation/Foundation.h>
#import <malloc/malloc.h>
#import <objc/runtime.h>
//struct NSObject_IMPL
//{
// Class isa;
//};
//
//struct MJPerson_IMPL
//{
// struct NSObject_IMPL NSObject_IVARS; // 8
// int _age; // 4
// int _height; // 4
// int _no; // 4
//}; // 24
struct NSObject_IMPL {
Class isa;
};
struct MJPerson_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
int _height;
int _no;
}; // 计算结构体大小,内存对齐,24
//struct MJStudent_IMPL
//{
// struct MJPerson_IMPL MJPerson_IVARS;
// int _weight;
//};
@interface MJPerson : NSObject
{
int _age;
int _height;
int _no;
}
@end
//@interface MJStudent : MJPerson
//{
// int _weight;
//}
//@end
@implementation MJPerson
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MJPerson *p = [[MJPerson alloc] init];
NSLog(@"%zd", sizeof(struct MJPerson_IMPL)); // 24。类型占用的内存大小
NSLog(@"%zd %zd",
class_getInstanceSize([MJPerson class]), // 24 所有成员变量占用的内存大小
malloc_size((__bridge const void *)(p))); // 32。MJPerson 占用的内存大小
}
///>为什么是32呢?
24正常 是因为结构体内存对齐
传到底层代码为24 但是系统分配给我们是32 是因为什么呢? 操作系统的内存对齐OC里面都是16的倍数。16 32 48 64 80 96 112 128 144 160 176 182 208。224 240。256
所以就分配给我们。32字节
return 0;
}
一个OC对象至少占用 16个字节。因为isa指针占用的字节数是8字节 儿系统规定至少为16个字节
苹果会自动对属性和成员变量进行分别重排从而优化内存 就是重排序 是内存变小
对象存储的信息包括。变量的值。isa
2.一个类只切只有一个类对象 里面存储的对象方法信息 成员变量的类型 名字
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];
Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = object_getClass(object1); ///> 返回isa指针
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); 输出的都一样
3.元类对象 类方法信息
Class objectMetaClass = object_getClass([object2 class]);
Class objectMetaClass = object_getClass(objectClass5);
Class objectMetaClass2 = [[[NSObject class] class] class];
/*
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;
}
*/
基本的类成员变量结构
struct ivar_t {
int32_t *offset;
const char *name;
const char *type;
//...
}
4.为什么Objective-C类不能动态添加成员变量
category添加属性使用运行时 仅仅是添加了set get方法 但是不会添加实力变量
5.Instance的isa指针指向哪里
指向类对象。用来寻找对象方法
类对象的isa指针指向元类对象 用来寻找类方法
类对象的superClass 和 元类对象的superClass
子类对象调用父类的对象方法
先用子类的isa找到子类的类对象。然后去找找不到 在用superClass指针去父类里面寻找
父类的superclass指针
对象方法找的是 类对象 类对象的superClass 找的是父类对象
类方法找的是元类对象
元类对象的isa指向根元类 跟元类也指向根元类
NSObject的superClass指向的是nil
NSObject 元类的superClass指向的是NSObject这个类
类方法的寻找轨迹。如果在跟元类里面都没有这个方法 会去跟类的对象方法里面寻找 没有在报错
![](https://img.haomeiwen.com/i1802382/bc632eebbeab039d.png)
image.png
6.OC的类信息存放在哪里
类方法存放在元类对象中
成员变量 属性 对象方法 协议 放在类对象中
成员变量的具体值存放在 实例对象中
main函数加载累的信息的时候 就会把类对象存放在内存中
类对象 元类对象在内存里面只有一份
Objective-C类成员变量深度剖析
网友评论