简单了解NSObject的‘底层实现’、‘占用内存’及‘分类’。
NSObject的底层实现
oc中
@interface NSObject {
Class isa;
}
@end
转为c++后 (64位系统中占8个字节,32位系统中占4个字节,以下均以64位系统为例)
struct NSObject_IMPL {
Class isa; // 占8个字节
};
Class实际上是一个指针
typedef struct objc_class *Class;
一个NSObject对象占多少内存?
从上面的NSObject底层实现看,既然NSObject的对象本质上是一个isa的Class指针,而Class又占用8个字节,那么一个NSObject对象是不是就占用8个字节呢?实际上不是,一个NSObject实际上占用16个字节。
alloc本质是在调用allocWithZone,其函数内部在分配内存时,会判断if( size < 16 ){size = 16},
总结:系统分配了16个字节给NSObject对象,但NSObject对象内部只使用了8个字节的空间(64bit环境下)。
NSObject *obj = [[NSObject alloc] init];
// 获得NSObject实例对象的 “成员变量” 所占用的大小(基于内存对齐原则,最大成员内存的倍数)
NSLog(@"%zd", class_getInstanceSize([NSObject class])); // 8
// 获得obj指针所指向的内存大小(16的倍数)
NSLog(@"%zd", malloc_size((__bridge const void *)obj)); // 16
OC对象的分类
- instance对象(实例对象)
NSObject *object = [[NSObject alloc] init];
- class对象(类对象)
每个类在内存中有且只有一个class对象Class objectClass1 = [object class]; Class objectClass2 = object_getClass(object); // -(void)test; 方法是保存在类对象里的
- meta-class对象(元类对象)
每个类在内存中有且只有一个meta-class对象#import <objc/runtime.h> // 将类对象传入,获得元类对象(如果传入instance实例对象,则返回的是class对象) Class objectMetaClass = object_getClass(objectClass); // 元类对象 Class objectClass2 = object_getClass(object); // 类对象 // +(void)test; 类方法是保存在元类对象里的
object_getClass:
Class object_getClass(id obj){
// 如果是instance对象,返回class对象;
// 如果是class对象,返回meta-class对象
// 如果是meta-class对象,返回NSobject(基类)的meta-class对象;
if (obj) return obj->getIsa();
else return Nil;
}
阅读量
loading...