iOS知识收集iOS DeveloperiOS Developer

深入理解objc中的类与对象

2016-08-16  本文已影响767人  ZhengLi

引言

促使我写这篇文章的主要原因是我发现平时利用的class方法与object_getClass函数的返回值竟然是不一样的,这与我之前理解的类的概念一直有所偏差。在查阅了部分资料后,发现对objc中关于类与对象有了一个新的理解,遂撰此文记录下。

为了更好的阅读体验,推荐到我的博客阅读。
码字不易,各位看官看的喜欢烦请点个赞吧!以示鼓励啊😢

深入了解类与对象

想要搞清楚这两个方法的区别,需要彻底搞清楚objc中关于类与对象的概念。

objc中对象与类的概念

objc中关于对象的定义如下:

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

可见对象是一个含有isa指针的结构体。那么isa指向的Class又是什么呢?

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

原来Class是一个指向objc_class结构体的指针,apple的注释写的很清楚,Class相当于objc中的类。所以只有我们搞明白了objc_class结构体到底是什么,也就搞清楚了objc中关于类的概念。
objc/runtime.h中关于该结构体的定义如下:

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;
/* Use `Class` instead of `struct objc_class *` */

虽然下面的一段串内容已经是OBJC2_UNAVAILABLE了,但依然可以看出一些apple关于class的定义的倪端:

  1. 我们注意到,objc_class结构体内部也含有一个isa指针,也就说“类也是有类的”。虽然读起来很拗口,但这也是为什么类有时候也被称为类对象的原因:类其实也是一个对象~
  2. 下面一段内容含有:类的方法列表(这些方法其实都是对象方法,至于为什么,后面解释),类的成员变量列表,类的cache列表,类的协议列表。更重要的是,它还有一个指向Classsuper_class指针。

接下来,我们来一一讲解这些东西到底都是干嘛的。


对象,类,元类

我们现在讲的类对象,就是中间的RootClass,ASuperClass,AClass。我们可以清晰的看到,此处的isa指针指向的是MetaClass,又译为元类。而所谓元类,就是类对象的类,也可以说是类对象的类对象

看到这里,你可能已经恍然大悟:对象的isa指针指向类对象,类对象的isa指针指向了元类。元类的isa指针指向根元类。三者统一了objc关于对象,类的基本概念。

#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

结合上面的元类概念,我们就能明白,原来苹果设计类对象的用意,就是为了存储对象的某些信息,比如对象方法,类遵守的一些协议,对象的属性,对象的类的父类(拗口。。。)等等。所以我们也就不能理解设计元类的用意:存储类的一些信息,比如类方法就存在元类里。相信读到这里,已经对objc中的对象和类有了一个很深刻的理解。下面说说我写这篇文章的主要原因:理解object_getClass函数与class方法。

理解object_getClass函数与class方法。

注:此处需要对runtime有了解

天天都在用的class方法

强大的runtime函数:object_getClass

原来NSNumber是类簇。这里还是简单的说说类簇的概念吧:一个父类有好多子类,父类在返回自身对象的时候,向外界隐藏各种细节,根据不同的需要返回的其实是不同的子类对象,这其实就是抽象类工厂的实现思路,iOS最典型的就是NSNumber


码字不易,各位看官看完如有收获烦请点个赞吧!以示鼓励啊😢
至此,终于写完了这篇文章。希望对大家有所帮助吧~~

上一篇下一篇

猜你喜欢

热点阅读