NSObject源码探究

  • 前言

NSObject对于OC开发者再熟悉不过了,阅读各大书籍,被灌输的概念就是NSObject是大部分类的基类(比如NSProxy就不是, 但是它实现了NSObject协议)我们探究的大致有Foundation/NSObject.hobjc/NSObject.hobjc/runtime.hobjc/objc.h这几个文件,So Lets start it.

NSObject源码探究_第1张图片
Foundation/NSObject.png

文件伊始,声明了一下几种类型

@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;

实现了NSCopying 和 NSMutableCopying协议

NSObject源码探究_第2张图片
Foundation/NSObject.png

后面也尽是一些对NSObject类的一些拓展,并没有找到我们想要的类定义。

我们看到头文件最上的import

NSObject源码探究_第3张图片
Foundation-NSObject.png

那么我们请移架

我们发现,定义了一个NSObject的协议


NSObject源码探究_第4张图片
objc/NSObject.h

往下翻找到了我们NSObject的定义


NSObject源码探究_第5张图片
objc/NSObject.h
@interface NSObject  {
    Class isa  OBJC_ISA_AVAILABILITY;
}

这里我们能的到的信息是,NSObject是一个遵循了NSObject协议的对象,他持有一个类型为Class的isa变量,那么问题来了,这个Class是什么?

点击Class定义,我们来到了

NSObject源码探究_第6张图片
objc/objc.h

我们可以看出Class是一个objc_class结构体的指针,

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

我们再看看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;

objc2下只有简简单单的Class isa OBJC_ISA_AVAILABILITY;
objc2之前还有父类指针,类名,实例列表结构体,版本信息,方法列表结构体等。

理一下思路:

@interface NSObject  {
    Class isa  OBJC_ISA_AVAILABILITY;
}
////////////////////
typedef struct objc_class *Class;
////////////////////
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
}

NSObject源码探究_第7张图片
NSObject.png

NSObject对象持有一个指向objc_class结构体的指针,这个结构体内也有一个isa指针,但是这个isa指针指向谁呢???
基本上从.h文件中我们是无从而知的。
那么我们从源码开刀 (:зゝ∠),好在苹果开源了runtime的代码 源码地址

  • NSObject.mm
    绕了一圈,又回到了NSObject对象 囧,不过也符合NSObject的主题啦,我们也一步步接近了真相 笑。
    直觉上,我们觉得isa,代表:“is a?”指代 “只是个什么东西囧”,
    我们觉得[NSObject class] 应该返回他是个什么东西也就是isa指针指向的内容,我们从这边入手。
- (id)self {
    return self;
}

+ (Class)class {
    return self;
}

- (Class)class {
    return object_getClass(self);
}

+ (Class)superclass {
    return self->superclass;
}

- (Class)superclass {
    return [self class]->superclass;
}

+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

我们关注这一个方法

- (Class)class {
    return object_getClass(self);
}

查看object_getClass的定义

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

解读为:若obj类型存在,返回obj->getIsa()否则返回NIL
getIsa()字面意思,符合我们的直觉,class方法返回 isa指针。

我们再关注

+ (Class)class {
    return self;
}

NSObject的class类型指向了自身

NSObject源码探究_第8张图片
Class

NSObject的实例方法和类方法,都返回的是NSObject对象自身,,我不禁陷入了沉思。。

经过查阅资料《Object-C编程全解》[日]荻原刚志,有了以下内容:

我们引入元类的概念,我们看下元类的概念:

NSObject源码探究_第9张图片
元类的概念.png

图中所示,类A是NSObject的子类,ClassB是ClassA的子类,类对象和实例对象都存在我们上面提到的isa指针中,isa指针类型是objc_class。

现在我们知道了,[NSObject class]返回的是NSObject的元类,
接下来我们看一个例子

BOOL wh = [[NSString class] isKindOfClass:[NSObject class]];

NSObject源码探究_第10张图片
元类.png

结果为YES,印证了 元类的概念.png图中元类的继承关系

那么,我们可以得出

类对象是继承了根类的元类对象的一个实例

另外我们通过元类的概念.png中的继承关系可以得到

类对象可以执行根类对象的实例方法

比如,类对象可以执行NSObject的实例方法performSelector:responseToselector:方法

你可能感兴趣的:(NSObject源码探究)