- 前言
NSObject对于OC开发者再熟悉不过了,阅读各大书籍,被灌输的概念就是NSObject是大部分类的基类(比如NSProxy就不是, 但是它实现了NSObject协议)我们探究的大致有Foundation/NSObject.h
和 objc/NSObject.h
和 objc/runtime.h
和 objc/objc.h
这几个文件,So Lets start it.
文件伊始,声明了一下几种类型
@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
实现了NSCopying 和 NSMutableCopying协议
后面也尽是一些对NSObject类的一些拓展,并没有找到我们想要的类定义。
我们看到头文件最上的import
那么我们请移架
我们发现,定义了一个NSObject的协议
往下翻找到了我们NSObject的定义
@interface NSObject {
Class isa OBJC_ISA_AVAILABILITY;
}
这里我们能的到的信息是,NSObject是一个遵循了NSObject协议的对象,他持有一个类型为Class的isa变量,那么问题来了,这个Class是什么?
点击Class定义,我们来到了
我们可以看出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对象持有一个指向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的实例方法和类方法,都返回的是NSObject对象自身,,我不禁陷入了沉思。。
- 续
经过查阅资料《Object-C编程全解》[日]荻原刚志,有了以下内容:
我们引入元类的概念,我们看下元类的概念:
图中所示,类A是NSObject的子类,ClassB是ClassA的子类,类对象和实例对象都存在我们上面提到的isa指针中,isa指针类型是objc_class。
现在我们知道了,[NSObject class]
返回的是NSObject的元类,
接下来我们看一个例子
BOOL wh = [[NSString class] isKindOfClass:[NSObject class]];
结果为YES,印证了
元类的概念.png
图中元类的继承关系
那么,我们可以得出
类对象是继承了根类的元类对象的一个实例
另外我们通过元类的概念.png
中的继承关系可以得到
类对象可以执行根类对象的实例方法
比如,类对象可以执行NSObject的实例方法performSelector:
和responseToselector:
方法