转载

iOS 简单粗暴的浅谈类与对象

简介:

在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对应的类;

iOS 简单粗暴的浅谈类与对象

如果一个类的跟类为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数据结构的机会,从苹果给我们的一些机制解释或者方法上可以灵活的运用与处理。

正文到此结束
Loading...