码迷,mamicode.com
首页 > 其他好文 > 详细

objectC 的isa 详解

时间:2015-12-27 17:49:33      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

每个Objective-C对象都有一个隐藏的数据结构,这个数据结构是Objective-C对象的第一个成员变量,它就是isa指针。

在NSObject.h里面: 

@interface NSObject <NSObject> {

    Class isa  OBJC_ISA_AVAILABILITY;

}

再点开 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

}

这一些定义对于懂的人自然懂,不会的人根本看不懂。建议看完下面的例子,再点开参考里面的链接仔细看一遍。

现在我们知道的是,对于我们新建的一个类,都会有一个隐藏的属性isa,可以通过它进行一些访问。

我们现在新建一个类ClassParent,继承于NSObject, 里面有成员方法-(void)selectorP,类方法+(void)ClassSelectorP。

再新建一个类ClassChild,继承于ClassParent,里面有成员方法-(void)selectorC, 类方法+(void)ClassSelectorC。

现在我们新建一个实例ClassChild* child = [ClassChlid new];

当我们调用[child class] 的时候,child就会通过isa指针去找到自己的类对象。

当我们调用[child superclass]的时候,child 就会通过super_class 去找到ClassParent的类对象。

在这里,再普及objc_class 的两种类型:

 class     实例对象(child)的isa指向的结构体;

metaclass  类对象(Child,注意大写)的isa指向的一个结构体;

接着,调用[child SelectorC],child通过isa找到实例对象的class,在class(注意看上面 struct objc_class 的定义)的方法列表里面找到SelectorC;

再试着调用[child SelectorP],child通过isa找到实例对象的class,发现class里面并没有这个方法,通过class里面的super_class找到ClassParent的class,在里面的方法列表找到了SelectorP;

再是类方法[Child ClassSelectorC],Child(请注意,这个是类对象)通过isa找到类对象的metaclass(实际上也是class,类型是一样的,只是为了区分而叫不一样的名字),在类对象的metaclass的方法列表里面找到了ClassSelectorC;

再试着调用[Child ClassSelectorP],Child通过isa找到类对象的metaclass,发现metaclass里面并没有这个方法,通过metaclass里面的super_class找到ClassParent的metaclass,在里面的方法列表找到了ClassSelectorP;

 

这是几个例子基本上已经涵盖了大多数调用的情况。

最后总结下:

child 是一个实例对象,可以有多个,isa指向的class也是有多个的;

Child 是一个类对象,只有一个,isa指向的metaclass只有一个。

最后为了理解class和metaclass的作用,大家可以换位思考一下,如果我们作为runtime的设计者,当开发者新建出来一个实例对象child的时候,我们应该存储child的属性和方法,同时又该如何响应其方法调用,最后还要记录与Parent之间的继承关系。

请注意的是,child实际上只是

 

 

参考

http://www.cocoachina.com/ios/20141018/9960.html

http://blog.csdn.net/jasonblog/article/details/7246822

http://blog.csdn.net/totogo2010/article/details/8081253

objectC 的isa 详解

标签:

原文地址:http://www.cnblogs.com/loying/p/5080429.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!