本帖最后由 FFFF001 于 2016-8-7 13:44 编辑
新手请学完基本知识之后再看这个,这里写的不是对象
objective-c运行时如果用到某个类的时候, 他会创建一个代表该类的类对象。(Class 类型) 类对象包含了指向超类的指针,类名,和指向 "类方法列表" 的指针(+-方法)。 类对象还包含一个long型数据,为新创建的类实例对象指定大小(以字节为单位) Student *stu = [[Student alloc] initWithName:@"小明" andAge:29 andScroe:89]; Class c_Stu1 = [stu class]; Class c_Stu2 = [Student class]; NSLog(@"%@", c_Stu1); NSLog(@"%@", c_Stu2); NSLog(@"%p", c_Stu1); NSLog(@"%p", c_Stu2); Class 就是类的类型. 其实Student类也是一个对象. c_Stu1 是一个类类型的变量 [stu class] [Student class] 将 "类在内存中的数据"(以下详解) 保存到 c_Stu 中, 也就是说可以通过 c_Stu来创建 Student 的对象了. Class 类型实际是一个指针 , 他只是 结构体 struct objc_class 的别名 typedef struct objc_class *Class;
struct objc_class { Class isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; Class实际就是上面的结构体
/*-------------------------------------------------------*/
类编译时在内存中开辟的空间详析 栈区: 存放对象地址,指向堆区 堆区: 开辟空间,存放对象属性,以及方法列表, isa指针指向 Class类对象(Student). 全局区: Class对象(Student),存放属性,方法列表.(方法的 SEL类型(指向代码区)). 代码区: 方法的实现. 以上步骤不代表在内存中开辟空间的先后顺序 当我们通过对象调用方法的时候, 1. 会先将方法封装为 SEL 类型, 2. 然后通过类指针指向我们的全局区, 3. 最后和全局区里的SEL类型的方法进行比对, 4. 比对成功,则进入代码区进行代码的实现,比对不成功则报错. 补充: 在我们调用 self和super方法时,会有调用父类还是自己本身类方法的选择, 在全局区里方法的SEL类型里有自己的方法,还有继承而来的父类方法, 当用self时,会告诉系统,此时全局区里调用的是自己的方法, 用super时则是调用父类的方法
|