探究OC对象本质
实例对象(Instance)
当我们调用NSObject *obj = [[NSObject alloc] init]生成的obj就是一个实例对象,实例对象在内存中的存储信息主要是一个指向**类对象(Class)**的isa指针和实例对象中所包含的成员变量。
@interface Person : NSObject
{
int _age;
}
@end
@implementation
@end
对于一个NSObject实例对象,经过编译后转化为了一个名为NSObject_IMPL的结构体
struct NSObject_IMPL {
Class isa;
};
对于一个继承自NSObject的Person类,经过编译之后,生成了一个名为Person_IMPL的结构体,在这个结构体中有一个NSObject_IMPL的结构体,由此可以看出,子类中包含了父类的所有信息。
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
};
类对象(Class)
类对象可以看做是对于实例对象的描述,在它的内存结构中包含了一个指向**元类对象(Meta Class)**的isa指针,一个指向父类的super_class指针,属性信息(name、version、instance_size…),成员变量信息(objc_ivar_list),对象方法列表(objc_method_list),协议信息(objc_protocol_list)等。
每个类在内存中只有一个类对象,类对象可以通过
Class objcClass = [NSObject class]获取,或者通过object_getClass(instance)获取,需要注意的是这里的instance必须是一个实例对象
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
元类对象(Meta Class)
元类对象可以看作是对类对象的描述,它的内存结构与类对象的内存结构完全一致,它在内存中的结构包括一个指向基类类对象(通常是NSObject)的isa指针,一个指向父类的super_class指针,类方法列表,以及其他信息。
下面这张图清晰地阐述了实例对象、类对象、元类对象三者之间的关系
@interface NSObject (HCTest)
- (void)test;
+ (void)test;
@end
@implementation NSObject (HCTest)
- (void)test
{
NSLog(@"test");
}
@end
在这里声明了一个NSObject的分类test,在test中声明并实现了对象方法,只声明了同名的类方法,但是未实现对应的类方法。
这个时候我们调用一下NSObject的类方法test
int main(int argc, const char * argv[]) {
@autoreleasepool {
[NSObject test];
}
return 0;
}
发现最后的打印结果是
2020-08-03 23:03:23.921946+0800 test[1139:149862] test
Program ended with exit code: 0
说明在调用NSObject的类方法+ (void)test的时候最后确实是调用的- (void)test,很好地说明了元类之间的继承关系;
在
arm64架构和X86架构中,实例对象的isa指针并不直接指向类对象的内存地址,而是对isa指针进行了位运算,同样类对象的isa指针也不是直接就指向元类对象的内存地址,也是进行了位运算之后才是真正的元类对象的内存地址
本文深入探讨Objective-C中对象、类与元类的关系,解析实例对象、类对象及元类对象的内存结构,揭示其内部工作原理,包括isa指针的作用及位运算细节。
1388

被折叠的 条评论
为什么被折叠?



