Objective-C 2.0 with Cocoa Foundation---NSObject的奥秘(4)

Objective-C 2.0 with Cocoa Foundation---NSObject的奥秘(4),第1张

概述6.4,重载方法的调用   让我们继续关注“06-NSobjecs.m”文件,请大家参考一下下面的代码:  1 Class cattle_class = cattle->isa;   2 MyClass my_cattle_class = cattle->isa;   3 SEL say = @selector(saySomething);   4 IMP cattle_sayFunc = [ca

6.4,重载方法的调用

  让我们继续关注“06-NSobjecs.m”文件,请大家参考一下下面的代码:

 1 Class cattle_class = cattle->isa;
  2 MyClass my_cattle_class = cattle->isa;
  3 SEL say = @selector(saySomething);
  4 IMP cattle_sayFunc = [cattle methodForSelector:say];
  5 cattle_sayFunc(cattle, say);
  6     
  7 Class redBull_class = redBull- >isa;
  8 MyClass my_redBull_class = redBull- >isa;
  9 
10 IMP redBull_sayFunc = [redBull methodForSelector:say];
11 redBull_sayFunc(redBull, say);

  本节的内容和6.3节的内容比较类似,关于代码部分笔者认为就不需要解释了,如果同学们有所不熟悉的话,可以参考一下第5章的内容。

  在我们的cattle类和Bull类里面,都有saySometing这个实例方法。我们知道只要方法的定义相同,那么它们的SEL是完全一样的。我们根据一个SEL say,在cattle和redBull对象里面找到了他们的函数指针。根据6.3节的讲述,我们知道当runtime接收到寻找方法的时候,会首先在这个类里面寻找,寻找到了之后寻找的过程也就结束了,同时把这个方法的IMP返回给我们。所以,在上面的代码里面的cattle_sayFunc和redBull_sayFunc应该是不一样的,如图6-4所示:

 

  图6-4, cattle_sayFunc和redBull_sayFunc的地址

  6.5,超类和子类中的Class

  在类进行内存分配的时候,对于一个类而言,runtime需要找到这个类的超类,然后把超类的Class的指针的地址赋值给isa里面的super_class。所以,我们的cattle里面的Class应该和redBull里面的Class里面的super_class应该是完全相同的,请参照图6-5:

 

  图6-5, cattle里面的Class和redBull里面的Class里面的super_class

  6.6,实例变量的内存分配的位置

  我们先来回忆一下对象是怎样被创建的。创建对象的时候,类的内容需要被调入到内存当中我们称之为内存分配(Allocetion),然后需要把实体变量进行初始化(Initialization),当这些步骤都结束了之后,我们的类就被实例化了,我们把实例化完成的类叫做对象(objecs)。

  对于内存分配的过程,runtime需要知道分配多少内存还有各个实例变量的位置。我们回到“MyNSobjecs.h”,参照如下代码:

1 typedef struct objc_ivar* Ivar_t;
2 typedef struct objc_ivar_List {
3     int   ivar_count;                             
4     struct objc_ivar {
5         const char* ivar_name;                    
6         const char* ivar_type;                      
7         int        ivar_offset;                           
8     } ivar_List[1];                              
9 } IvarList, *IvarList_t;

  我们仔细看看第5行的ivar_name,顾名思义这个是实例变量的名字,第6行的ivar_type是实例变量的类型,第7行的ivar_offset,这个就是位置的定义。runtime从类的isa里面取得了这些信息之后就知道了如何去分配内存。我们来看看图6-6:

 图6-6,实例变量在内存中的位置

  在cattle里面,我们看到了第一个实例变量是isa,第二个就是我们定义的legsCount。其中isa是超类的变量,legsCount是cattle类的变量。我们可以看出来,总是把超类的变量放在前头,然后是子类的变量。

  那么对于redBull而言是什么样子呢?我们来看看图6-7

 

  图6-7,redBull里面的实例变量的位置

  我们通过图6-7可以发现redBull的Class里面的skincolor的位置偏移是8,很明显,runtime为isa和legsCount预留了2个位置。

总结

以上是内存溢出为你收集整理的Objective-C 2.0 with Cocoa Foundation---NSObject的奥秘(4)全部内容,希望文章能够帮你解决Objective-C 2.0 with Cocoa Foundation---NSObject的奥秘(4)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1065745.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存