OC追根溯源之Class
前两天碰到一面试题:
//分辨下面res的是非
BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
BOOL res2 = [[NSObject class] isMemberOfClass:[NSObject class]];
BOOL res3 = [[Sark class] isKindOfClass:[Sark class]];
BOOL res4 = [[Sark class] isMemberOfClass:[Sark class]];
在这之前,我们先了解一下相关的定义:
Class
在objc.h
中Class
是这么定义的:
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
objc_class
又是啥呢?在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;
MetaClass
上面能看到Class
中有个isa
参数,它是指向Class
的元类(MetaClass)
的指针。
注意到isa
也是一个Class
的结构体,也就是说MetaClass
其本质也是一个Class
。
我们可以把Meta Class理解为 一个Class对象的Class。简单的说:
- 当我们发送一个消息给一个NSObject对象时,这条消息会在对象的类的方法列表里查找
- 当我们发送一个消息给一个类时,这条消息会在类的Meta Class的方法列表里查找
之后就有了下面的这张图:
能看到:
- 每个
Class
都有一个isa
指针指向一个唯一的MetaClass
- 每一个
MetaClass
的isa
指针都指向最上层的MetaClass
(图中的NSObject
的MetaClass
) - 最上层的
MetaClass
的isa
指针指向自己,形成一个回路 - 每一个
MetaClass
的super class
指针指向它原本Class
的Super Class
的MetaClass
。 - 最上层的
MetaClass
的Super Class
指向NSObject
Class
本身 - 最上层的
NSObject
Class
的super class
指向nil
接下来我们看看objc
源码中(源码可到这里下载),在文件Object.mm
内,上面相关方法的定义:
+ (Class)class {
return self;
}
- (BOOL)isKindOf:aClass
{
Class cls;
for (cls = isa; cls; cls = cls->superclass)
if (cls == (Class)aClass)
return YES;
return NO;
}
- (BOOL)isMemberOf:aClass
{
return isa == (Class)aClass;
}
那么,BOOL res1 = [[NSObject class] isKindOfClass:[NSObject class]];
就可以这样对应起来理解了:
[NSObject class]
拿到的是self
,类方法的return self
,即上图紫色的NSObject(Class)
。
根据上面- (BOOL)isKindOf:aClass
的实现,for
循环首先拿到的cls = isa
,也就是cls
为NSObject(Class)
的MetaClass
。显然这时候cls == (Class)aClass
不成立。
随后,cls = cls->superclass
,即cls
变成了NSObject(Class)
的MetaClass
的superclass
,根据图示可以,superclass
指向的是NSObject(Class)
,至此cls == (Class)aClass
成立,返回YES
。
同样的道理,分析BOOL res3 = [[Sark class] isKindOfClass:[Sark class]];
:
[Sark class]
拿到的是Sark(Class)
,而- (BOOL)isKindOf:aClass
中cls
拿到的值依次是Sark Meta Class
->NSObject Meta Class
->NSObject Class
-> nil
,没有相等的,return NO
。
剩下两个,根据- (BOOL)isMemberOf:aClass
的实现,很容易得出结论会return NO
。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Windows Phone 8 开发初体验
Windows Phone 8 是当前除了Android、IPhone之外,第3大智能手机运行平台。作为微软技术的忠实fans,一直关注和跟进微软技术的最新进展。这里就给大家简单介绍一下,如何进行Windows Phone 8 的开发。 开发Windows Phone 8应用或者游戏,首先得搭建开发环境。 操作系统必须为64位Windows 8或以上,开发工具VS版本为VS2012或以上。这里的VS推荐安装VS2012 Ultimate版本,http://www.microsoft.com/zh-cn/download/details.aspx?id=30678。当然你也可以安装VS2013,对应操作系统Windows 8.1。 安装好VS2012 Ultimate之后,我们找到Windows平台安装程序,如果本机没有找到,也可以从这里下载安装:http://www.microsoft.com/web/downloads/。 安装好Windows平台安装程序之后我们运行它,显示如下界面。 我们在产品—工具里面选择Windows Phone SDK 8.0进行安装。当然这里面有很多其它的...
-
下一篇
Android requires compiler compliance level 5.0. Please fix project pro...
1.项目右键 ->android tools->Fix Project 2.如果不可以,检查Project->Properties->Java Compiler 确认JDK compliance被设置为1.6,并且enable specific seetings. 本文转自曾祥展博客园博客,原文链接:http://www.cnblogs.com/zengxiangzhan/archive/2011/03/15/1985505.html,如需转载请自行联系原作者
相关文章
文章评论
共有0条评论来说两句吧...