简介:
在Objective-C语言中,每一个地方我们都在面对类与对象,比如说一个控件、一个字符串、一张图片、包括我们所说的NSObject等等都可以看做对象,那么Objective-C的类呢也就是所谓的Class,Class也是一个对象,称为类对象,既然无论何时何地面对对象,哈哈那么你对你的对象了解多少呢?是不是又开始想淫荡的去研究一下???
正文:
类与对象在Objective-C中算是非常基本的东西,可以说无时无刻不遇到,创建的任何东西都可以认为是一个对象,在无时无刻的不创建类,那么接下来我们将简单探讨一下类与对象
首先来看一下class与object在Objective-C的定义,路径为/usr/include/objc/objc.h:
typedef struct objc_class *Class;//一个不透明含糊的类型,表示一个Objective-C类
typedef struct objc_object {//表示类的实例
Class isa;
} *id;//指向类实例的指针
我们可以看到Class是一个objc_class结构类型的指针,文件中注释为AnopaquetypethatrepresentsanObjective-Cclass;id(任意对象)是一个objc_object结构类型的指针,文件中注释为Apointertoaninstanceofaclass;
以下是objc_class结构体的一个体现,这里我们来挨个注释:
struct objc_class { struct objc_class* isa; struct objc_class* super_class; const char* name; long version; long info; long instance_size; struct objc_ivar_list* ivars; struct objc_method_list** methodLists; struct objc_cache* cache; struct objc_protocol_list* protocols; };
isa指针:是一个类型为objc_class指针,是的和class是一个类型的指针,那么我们是不是可以这样说:一个以objc_class指针指向的所有东西都可以当作一个objc对象来对待
super_class:父类,那么我们知道所有的类都继承于NSObject或者NSProxy,那么NSObject是所有类的父类唠,那NSObject或者NSProxy的super_class是什么呢,我们可以直接从项目直接打印下试试看!
NSLog(@"%@",NSObject.superclass); 2017-10-09 16:32:56.195134+0800 MetaClass[17818:4363641] (null)
由此可见如果一个类的根类为NSObject或者NSProxy,那么这个类的super_class为我们打印的值为null
在《深入浅出Cocoa教程》中提到
好,先中断一下其他类结构成员的介绍,让我们理清一下在继承层次中,子类,父类,根类(这些都是普
通class)以及其对应的metaclass的isa与super_class之间关系:
规则一:类的实例对象的isa指向该类;该类的isa指向该类的metaclass;
规则二:类的super_class指向其父类,如果该类为根类则值为NULL;
规则三:metaclass的isa指向根metaclass,如果该metaclass是根metaclass则指向自身;
规则四:metaclass的super_class指向父metaclass,如果该metaclass是根metaclass则指向
该metaclass对应的类;
如果一个类的跟类为NSObject或者NSProxy那么是不是可以把她的super_class理解为他自己本身呢?
name:constchar*name;一个c类型的字符串,用来表示类的名字
在运行时可以通过方法idobjc_getClass(constchar*aClassName)来得到这个类的名字,通过idobjc_getMetaClass(const
char*aClassName)来得到该类的metaclass
version:版本信息,初始默认值为0
当然也可以在运行时通过方法class_setVersion修改版本信息,通过class_getVersion来得到版本信息
info:此处同样来引用《深入浅出Cocoa教程》中的解读:
供运行期使用的一些位标识。有如下一些位掩码:
CLS_CLASS (0x1L)表示该类为普通class,其中包含实例方法和变量;
CLS_META (0x2L)表示该类为metaclass,其中包含类方法;
CLS_INITIALIZED (0x4L)表示该类已经被运行期初始化了,这个标识位只被objc_addClass所设置;CLS_POSING (0x8L)表示该类被pose成其他的类;(poseclass在ObjC 2.0中被废弃了);CLS_MAPPED (0x10L)为ObjC运行期所使用
CLS_FLUSH_CACHE (0x20L)为ObjC运行期所使用
CLS_GROW_CACHE (0x40L)为ObjC运行期所使用
CLS_NEED_BIND (0x80L)为ObjC运行期所使用
CLS_METHOD_ARRAY (0x100L)该标志位指示methodlists是指向一个objc_method_list还是
一个包含objc_method_list指针的数组;
instance_size:这个类实例变量的大小,内包含了从父类继承下来的实例变量
ivars:可以看出这个是一个指向objc_ivar_list类型的指针,用处呢是用来存储每一个实例变量的地址
methodLists:此处和info的解读方式一样,参考《深入浅出Cocoa教程》,讲的很不错
与info的一些标志位有关,CLS_METHOD_ARRAY标识位决定其指向的东西(是指向单个objc_method_list还是一个objc_method_list指针数组),如果info设置了CLS_CLASS则objc_method_list存储实例方法,如果设置的是CLS_META则存储类方法;
cache:同样道理指向objc_cache的指针,cache可以看出这个是一个缓存相关的,那么用来缓存什么呢,这就是用来存储最近使用方法的一个东西,来提高效率,优化
protocols:当然可以看出这一个objc_protocol_list的指针,用来存储声明遵守的正式协议
总结:
Objective-C,每一个地方我们都在面对类与对象,很明显的可以看出Objective-C提供了运行时期限来创造定义objc_class数据结构的机会,从苹果给我们的一些机制解释或者方法上可以灵活的运用与处理。