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

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所示:

objecsive-C 2.0 with Cocoa Foundation--- 6,NSobjecs的奥秘

 

  图6-4, cattle_sayFunc和redBull_sayFunc的地址

  6.5,超类和子类中的Class

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

objecsive-C 2.0 with Cocoa Foundation--- 6,NSobjecs的奥秘

 

  图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:

objecsive-C 2.0 with Cocoa Foundation--- 6,NSobjecs的奥秘

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

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

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

objecsive-C 2.0 with Cocoa Foundation--- 6,NSobjecs的奥秘

 

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

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值