美文网首页程序员
iOS 简单粗暴的浅谈类与对象

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

作者: a437e8f87a81 | 来源:发表于2017-10-09 21:53 被阅读0次


    简介:

    在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结构类型的指针,文件中注释为An opaque type that represents an Objective-C class;id(任意对象)是一个objc_object结构类型的指针,文件中注释为A pointer to an instance of a class;

    以下是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:const char* name;一个c类型的字符串,用来表示类的名字

    在运行时可以通过方法id objc_getClass(const char *aClassName)来得到这个类的名字,通过id objc_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数据结构的机会,从苹果给我们的一些机制解释或者方法上可以灵活的运用与处理,有兴趣一起交流学习的小伙伴,欢迎加入技术交流q群:150731459,一起进步!共同努力!有理解不正确和不合适的地方换欢迎大家指出,互相学习!

    最后送出分享几句话:

    当交流有矛盾的时候一定要及时沟通,假如来说两个人有矛盾一定要两个人单独在一起谈,谦卑,理解,放下心态谈通了为止!

    有一句话叫三人行必有我师,话糙理不糙,互相学习,共同进步!一起加油吧!

    C博客地址

    相关文章

      网友评论

        本文标题:iOS 简单粗暴的浅谈类与对象

        本文链接:https://www.haomeiwen.com/subject/msqyyxtx.html