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这个类
类方法的寻找轨迹。如果在跟元类里面都没有这个方法 会去跟类的对象方法里面寻找 没有在报错
image.png
6.OC的类信息存放在哪里
类方法存放在元类对象中
成员变量 属性 对象方法 协议 放在类对象中
成员变量的具体值存放在 实例对象中
main函数加载累的信息的时候 就会把类对象存放在内存中
类对象 元类对象在内存里面只有一份
Objective-C类成员变量深度剖析
网友评论