zoukankan      html  css  js  c++  java
  • Objective-C的动态设计

    我们都知道,Objective-C是一门动态语言,它的Runtime机制往往能让我们实现一些黑魔法。那么,这门语言是如何实现它的动态特征的呢?

    下面我们来刨根问底看个究竟。

    在Objective-C中,我们用到的几乎所有的类都是NSObject类的子类,NSObject类的定义如下:

    @interface NSObject <NSObject> {
    Class isa;
    }

    就一个Class 类型的isa实例变量,Class是什么类型?我们切入看一下

    Class 是一个 struct objc_class *的指针,struct objc_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

    } OBJC2_UNAVAILABLE;

    看到这里大家可能又晕了,怎么又有一个isa?这些isa是什么?之间有什么联系?

    其实,Objective-C中任何类定义都是一个对象。即在程序启动的时候任何类定义都对应于一块内存。在编译的时候,编译器会给每一个类生成一个且只生成一个”描述其定义的对象”,也就是苹果公司说的类对象(class object),他是一个单例(singleton)。每个实例的isa指针就会指向它对应的类对象。而这个类对象会存储它的实例的相关信息,包括实例方法、实例变量、实现的协议等。

    从上面的结构体中我们可以看到,类对象也拥有一个isa指针,这个指针又指向何处呢?

    我们知道,对象都是由类实例化而来的,那么类对象也是某个类实例化而来的,类对象的isa指针就指向这个实例化他的类的对象,我们称这个类为元类,元类存储了类的相关信息(其中主要包括类方法列表)。

    还是有些不明白?下面这个图标可能会有些帮助:

    也就是说,在编译的时候,编译器会对每一个类生成一个类对象和一个元类对象,来存储这个类的相关信息。当我们实例化一个对象的时候,是根据这个类对象包含的信息实例化的。

    既然这类是一个对象,那么,它的成员值就可以改变,这就个了我们动态改变一个类的无线可能。

    我们可以动态的向方法列表中添加方法、甚至新添加一个类等等。

    但是我们不能动态的添加实例变量,因为实例变量存储在ivars中,而ivars是struct objc_ivar_list *类型,在编译完成后类对象的存储空间不能改变,也就意味着ivars不能改变,因而不能动态的添加实例变量。这也是分类中不能添加实例变量的原因。

    可能有的童鞋会问,那为什么可以添加实例方法呢?

    从类的结构体中可以发现,methodLists是struct objc_method_list **类型的,意味着类对象中只是存了一个列表的指针,而实际方法列表的容器并不存储在类对象中。

    参考文章:Objective-C对象之类对象和元类对象

  • 相关阅读:
    php解析.csv文件
    sublime text3 输入中文的解决方法
    git 的使用
    yii2.0 框架邮件的发送
    yii2.0的分页和排序
    php上传图片文件常用的几个方法
    在yii框架中如何连接数据库mongodb
    yii框架中验证器声明一组内置验证器可以使用短名称引用
    yii中的cookie的发送和读取
    ExpressionToSQL
  • 原文地址:https://www.cnblogs.com/yueyuanyueyuan/p/7307435.html
Copyright © 2011-2022 走看看