1.对象的存储细节
- 类创建对象,每个对象在内存中都占据一定的存储空间,每个对象都有一份属于自己的单独的成员变量,所有的对象公用类的成员方法,方法在整个内存中只有一份,类本身在内存中占据一份存储空间,类的方法存储于此。(实例对象isa指针-->类对象方法列表)
2.isa指针
- 每一个对象都包含一个isa指针.这个指针指向当前对象所属的类。
- [p eat];表示给p所指向的对象发送一条eat消息,调用对象的eat方法,此时对象会顺着内部的isa指针找到存 储于类中的方法,执行。
- isa是对象中的隐藏指针,指向创建这个对象的类。
-
通过isa指针我们可以在运行的时候知道当前对象是属于那个Class(类)的
3.使用一个类创建多个对象
Car *car1 = [Car new];
Car *car2 = [Car new];
- 左侧栈内存存储两个指针car1,car2,分别记录着对内存中两个实例对象的内存地址
- 最右侧为Car类对象(Car元类的实例),拥有着对象方法列表,通过类对象,创建了car1,car2两个实例对象,实例对象中没有方法列表,只有成员变量,外加一个isa指针,它保存这类对象的内存地址.
4.补充
//NSObjct 分类.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (func)
-(void)food;
@end
NS_ASSUME_NONNULL_END
//NSObjct 分类.m
#import "NSObject+func.h"
@implementation NSObject (func)
-(void)food{
NSLog(@"food");
}
@end
//控制器
- (void)viewDidLoad {
[super viewDidLoad];
[NSObject food];
[[NSObject new] food];
}
//输出:
food
food
[NSObject food];方法在执行时,由于是类方法,找到NSObject元类,并不会找到food方法,于是去找其父类的方法列表,由于NSObject是根元类,他的父类为NSObject类对象,在类对象中找到了food方法,所以此处不会崩溃.这里NSObject元类对应的上图的右上角的根元类,NSObject类对象对应跟元类的父类.只有可以做根元类的类可以这么玩!!!如果是其他类,在没有做消息转发的情况下,必崩!!!总之,NSObject比一般的类牛逼一丢丢