• isa基础知识


    一、在c++中静态变量和静态函数可以通过类来访问(实例对象也可以访问),而一般的变量都是通过实例对象来访问。

    在oc中也有类对象和实例对象下面就来看看什么是ios中的类对象

    1、类对象(class object)  它是个对象,是占用内存空间的一个变量,这个对象在编译的时候编译器就生成了,专门来描述某个类的定义),

    这个类对象包含了Objective-C对象的一些信息包括Objective-C对象的方法调度表,实现了什么协议等等。这个包含信息就是Objective-C动态能力的根源了。

    2、Object-C对类对象与实例对象中的 isa 所指向的类结构作了不同的命名:类对象中的 isa 指向类结构被称作 metaclass,metaclass 存储类的static类成员变量与static类成员方法(+开头的方法);实例对象中的 isa 指向类结构称作 class(普通的),class 结构存储类的普通成员变量与普通成员方法(-开头的方法).

    这也就是说通过类对象访问静态变量和函数 实例对象访问普通的变量和函数

    二、类与对象

    那我们看看isa指针类型的数据结构是什么样的?如果抛开NSObject对象的其他的成员数据和变量,NSObject可以看成这样:

    1. @interface NSObject <NSObject> {  
    2.      Class    isa;  
    3. }   

    不考虑@interface关键字在编译时的作用,可以把NSObject更接近C语言结构表示为:

    1. struct NSObject{  
    2.    Class isa;  
    3.  }  

    Class是用typedef 定义的

    Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。它的定义如下:

    1
    typedef struct objc_class *Class;

    那NSObject可以这么写了

    1. struct NSObject{  
    2.   objc_class *isa  
    3. }  

    查看objc/runtime.h中objc_class结构体的定义如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    struct objc_class {
        Class isa  OBJC_ISA_AVAILABILITY;
     
    #if !__OBJC2__
        Class super_class                       OBJC2_UNAVAILABLE;  // 父类
        const char *name                        OBJC2_UNAVAILABLE;  // 类名
        long version                            OBJC2_UNAVAILABLE;  // 类的版本信息,默认为0
        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;

    在这个定义中,下面几个字段是我们感兴趣的:

    isa:需要注意的是在Objective-C中,所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass(元类),我们会在后面介绍它。

    super_class:指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。

    cache:用于缓存最近使用的方法。一个接收者对象接收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象。在实际使用中,这个对象只有一部分方法是常用的,很多方法其实很少用或者根本用不上。这种情况下,如果每次消息来时,我们都是methodLists中遍历一遍,性能势必很差。这时,cache就派上用场了。在我们每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果cache没有,才去methodLists中查找方法。这样,对于那些经常用到的方法的调用,但提高了调用的效率。

    version:我们可以使用这个字段来提供类的版本信息。这对于对象的序列化非常有用,它可是让我们识别出不同类定义版本中实例变量布局的改变。

     其他变量的详解

    isa指针:指向该对象所属类型的类型对象(Class Object)。在Objective-C中,类也是用对象来表示的,而类的isa指针指向它的metaclass(存储静态成员变量和类方法)。
    super_class指针:指向父类。
    name:类名称。
    version:类的版本信息。
    info:运行期使用的标志位,比如0x1(CLS_CLASS)表示该类为普通class,0x2(CLS_META)表示该类为 metaclass。
    instance_size:实例大小,即内存所占空间。
    ivars:指向成员变量列表的指针。
    methodLists:根据标志位的不同可能指向不同,比如可能指向实例方法列表,或者指向类方法列表。
    cache:因为Objective-C的消息转发需要查找dispatch table甚至可能需要遍历继承体系,所以缓存最近使用的方法。
    protocols:类需要遵守的协议。

     
    2:对象id:
         typedef struct objc_object {
             Class isa;
         } *id;
        可以发现, id可以用来表示任意一个对象,它是一个 objc_object 结构类型的指针,其第一个成员是一个 objc_class 结构类型的指针。
        我们的根类NSObject也同样是只有一个Class成员:
       @interface NSObject <NSObject> {
           Class       isa;
        }
        这个isa到底是什么呢?官方介绍是这样的:
        Every object is connected to the run-time system through its isa instance variable, inherited from the NSObject class. isa identifies the object's class; it points to a structure that's compiled from the class definition. Through isa, an object can find whatever information it needs at run timesuch as its place in the inheritance hierarchy, the size and structure of its instance variables, and the location of the method implementations it can perform in response to messages.
        可见,一个对象(Object)的isa指向了这个对象的类(Class),而这个对象的类(Class)的isa指向了metaclass。这样我们就可以找到静态方法和变量了。


     3: 运行时: 
         Objective-C的运行时是动态的,它能让你在运行时为类添加方法或者去除方法以及使用反射。这在其它语言是不多见的。

         类的实例对象的 isa 指向它的类;类的 isa 指向该类的 metaclass;
         类的 super_class 指向其父类,如果该类为根类则值为 NULL;
         metaclass 的 isa 指向根 metaclass,如果该 metaclass 是根 metaclass 则指向自身;
         metaclass 的 super_class 指向父 metaclass,如果该 metaclass 是根 metaclass 则指向该 metaclass 对应的类;
         Object-C 为每个类的定义生成两个 objc_class ,一个普通的 class,另一个即 metaclass。我们可以在运行期创建这两个 objc_class 数据结构,然后使用 objc_addClass将 class 注册到运行时系统中,以此实现动态地创建一个新的类。
  • 相关阅读:
    axios的拦截请求与响应
    Vue.mixin言简意赅的示例
    vue的formdata图片预览以及上传
    vue页面更新数据
    vue对象比较,阻止后退
    vue检索内容
    vue侧滑菜单
    JavaScript易错知识点整理
    写好你的JavaScript
    LeetCode123 Best Time to Buy and Sell Stock III
  • 原文地址:https://www.cnblogs.com/HypeCheng/p/4517751.html
Copyright © 2020-2023  润新知