底层原理(二)对象的本质2 补充

161 阅读1分钟

前言

上一片文章谈了对象的本质,我们只讨论了NSObject , 那么我们如果创建一个对象继承自NSOject里面有属性是什么样子的呢?

  • 当对象里面有成员变量是怎么样的?
  • 当对象里面是成员属性的时候是怎么样的?

成员变量

我们在 main.m 当中 LBStudent , 定义如下属性:

@interface LBStudent : NSObject

@end

@interface LBStudent ()  {
    int _age;
    int _no;
}

@end

@implementation LBStudent

@end

我们看下代码调用:

NSLog(@"%zd",sizeof(s)); // 这里sizeof 在便衣的时候就已经知道了s的类型。属于编译期间的
NSLog(@"%zd",class_getInstanceSize([s class]));
NSLog(@"%zd", malloc_size((__bridge const void *)s));

我们clang -rewrite-objc main.m -o main.o

struct NSObject_IMPL {
	Class isa;
};
struct LBStudent_IMPL {
	struct NSObject_IMPL NSObject_IVARS; 
	int _age;
	int _no;
};

我们看打印:

2020-01-20 16:52:37.347988+0800 msgSendDemo[34919:90631339] 8
2020-01-20 16:52:37.348247+0800 msgSendDemo[34919:90631339] 16
2020-01-20 16:52:37.348279+0800 msgSendDemo[34919:90631339] 16
Program ended with exit code: 0

至此我们知道了我们存入的是成员变量的时候占据的对象大小。

成员属性

打印下来发现是一样的,唯一不同的是,里面多了getter 和 setter 方法。

static int _I_LBStudent_age(LBStudent * self, SEL _cmd) { // getter
    return (*(int *)((char *)self + OBJC_IVAR_$_LBStudent$_age)); 
}
static void _I_LBStudent_setAge_(LBStudent * self, SEL _cmd, int age) { // setter
    (*(int *)((char *)self + OBJC_IVAR_$_LBStudent$_age)) = age; 
}