黑马程序员技术交流社区

标题: 探讨Object-C类和对象的本质 [打印本页]

作者: 楚燮哥哥    时间: 2014-12-1 14:34
标题: 探讨Object-C类和对象的本质
本帖最后由 楚燮哥哥 于 2014-12-1 15:03 编辑

   最近在看mj老师讲的类的本质,自己也上网找了下资料,对mj老师讲的做一个总结和扩展。   我们都知道每个对象都是由类创建出来的,每个Object-C对象实例都是指向某块内存数据的指针,所以在声明变量时,类型后都需要有一个“*”字符,例如:
  1. NSString *someString = @"someObject";
复制代码
该变量someString中存放的是这个字符串对象在内存中的地址,而NSString自身的数据就存放于该地址中,众所周知,对象所占的内存总是分配在“堆空间”(heap space)中,而指向该实例的变量总会被分配在“栈”(stack)上,他们此时在内存中的布局如下:

[attach]59715[/attach]
如果把对象所需的内存分配在栈上,则编译器会报错,例如
  1. NSString someString = @"someObject";
复制代码
会报如下错误 :Interface type cannot be statically allocated,翻译过来就是接口类型不能静态分配(本人只会谷歌翻译:#),可以理解为无法为该变量分配内存吧
  对于通用的对象类型id,由于其本身已经是指针来,所以就无需跟上*字符,于是就有
  1. <font size="3">id someString = @"someObject";</font>
复制代码
这种写法虽然简洁,但由于没有在对象声明时指定具体类型,所以在其调用本身没有的方法时,编译器并不会报错。  描述Object-C对象所用的数据结构定义在运行期程序库的头文件里,id类型本身也是定义在这里:
  1. typeof struct obj_object{
  2.   Class isa;
  3. } *id;
复制代码
由上可见,每个对象结构体的首个成员是Class类的变量。该变量定义了对象所属的类,通常称为“isa”指针,例如刚才的例子中所用的对象@"someObject"是一个(isa)NSString,isa指针就指向NSString,借此也可以说明类也是有类型的(Class isa这句代码本身就足以说明了),也就是说类本身也是一个对象,该对象的类型是Class,叫做类对象,而通过类创建的对象就叫类型的对象。例如有一个Person类,类中有一个类方法test(),那么就可以:

  1. [Person test];
  2. Class c =[[[Person alloc] init] class];
  3. [c test];
复制代码
大致也可以说Class是所有类的类型。

Class对象也定义在运行期程序库的头文件中:
  1. typedef struct objc_class *Class;
  2. struct objc_class {
  3. Class isa;
  4. Class super_class;
  5. const char *name;
  6. long version;
  7. long info;
  8. long instance_size;
  9. ……
  10. };
复制代码
此结构体中存放类的“元数据”(metadata),例如类的实例实现类几个方法,具备多少个实例变量等信息。结构体的首个变量也是isa指针,这说明Class本身也为Object-C对象。结构体里还有个变量叫super_class,它定义了本类的超类。类对象所属的类型(也就是isa指针所指向的类型)是另外一个类,叫做“元类”(metaclass),用来表述类对象本身所具备的元数据。前面我们一直所学的“类方法”就定义在此处,因为这些方法可以理解成类对象的实例方法。每个类仅有一个“类对象”,而每个“类对象”也仅有一个与之相关的“元类”。

  假设有个名为someClass的子类从NSObject中继承而来(个人觉得NSObject类似于java中的final类),则其继承体系如下:

结构体中的super_class指针确立了类对象与元类之间的继承关系,而isa指针描述了实例所属的类。
以上这些就是所谓的“类继承体系”了。
至于类的加载无非就是程序启动时加载项目中的所有类,加载完毕后会只调用一次类的+load()方法,而当使用某个类时,就会调用该类的+initialize()方法为该类进行初始化,类加载和初始化的顺序为先父类后子类。










作者: xiaoqu1998    时间: 2014-12-2 08:52
学习了~~~~~~~~~~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2