文档章节

Object-c 结构体模拟类

gaoios
 gaoios
发布于 2014/01/04 11:22
字数 1140
阅读 115
收藏 0

NSObject介绍

    假如没有面向对象的语言,那么结构化的程序设计语言如何模拟类哪?那自然就想到了结构体,其实objective c是在c语言的基础上发展的,同样NSObject也是用结构体来实现的。首先来看下一段结构体模拟类的代码吧。

typedef struct my_objc_class *MetaClass;

typedef struct my_objc_class *MyClass;

struct my_objc_class {

    MetaClass class_pointer;

    struct my_objc_class* super_class;

    const char* name;

    long version;

    unsigned long info;

    long instance_size;

    struct objc_ivar_list* ivars;

    struct objc_method_list* methods;

    struct sarray * dtable;

    struct my_objc_class* subclass_list;

    struct my_objc_class* sibling_class;

    struct objc_protocol_list *protocols;

    void* gc_object_type;

};

//这里就是自己定义一个类了。

MyClass student;

估计你看完这个结构体,会惊奇的说原来这就是NSObject啊,其实这不是NSObject的原型,因为苹果公司一向不喜欢开源,她的代码我们怎么可能得到那。上面的结构体,是GCC中定义的开源代码,从网上都可以下到,这就是一个类是如何用结构体实现的。下面我们就来逐行分析下这个结构体吧,来揭示一下类的本质。

1)class_pointer 

顾名思义就是这个结构体本身的一个指针,相信大部人都知道java和c++中的this关键字的用法吧,在c++中this指针就是这里的class_point。而objective c则是用的self来表示自身的指针的。

2)super_class 

看到这里就知道继承是怎么回事了吧,就是在结构体里放上一个指针指向它的父节点。懂得了这点如果想要实现c++中的多重继承,无非就是用指针数组或者链表就可以了。

3)name version和info

放到一块说了,因为她们都大同小异。name就是你定义的类的名字。任何产品都要有个版本吧,类同样也是人们设计出来的产品,version就是要给你的类加一个版本号,方便日后升级。info就是相当于一个ID,来区分你创建了多少个这样的结构体,也就是类。

4)instance_size 

这就是类的关键部分,在类中叫成员变量,这个大小是如何分配的,是根据你在类中定义了多少实例。这样在这个类去初始化的时候,就会读取instance_size中的数据,在c语言中就用malloc给这个结构体分配大小。

5)ivars 

表示的是类成员变量的列表,成员变量在分配好大小之后,ivars就存取了她们的地址,从而可以方便的访问到成员变量。所以说c++对类成员变量作用区域的限制,如pravite都是语法上的限制,如果你知道类是如何设计的,就可以先读取类的地址,接着让指针偏移一个变量的大小就可以访问到类中pravite的变量了。

6)methods 

方法列表,和实例变量设计的类似,无非这个列表是个函数指针列表吧了,存的都是函数指针。这里就不赘余了。

7)dtable 

这个要就是一些语言可以实现动态绑定的关键,在c++中这就是一个虚表,当这个虚表中有数据的时候,函数调用的时候就会首先在methods列表中找到方法的地址,然后从dtable查找符合这个方法应该有多少偏移量,从而访问到正确的地址。objective c中消息同样也是这样实现的。下面是objective c每次方法调用时都会调用lookup这个方法。

objc_msg_lookup(id receiver, SEL op)

{

  if (receiver)

    return sarray_get(receiver -> class_pointer -> dtable, (sidx)op);

  else

    return nil_method;

8)subclass_list

 是子类的列表指针这里不再赘余。

9) sibling_class 

是兄弟类的列表,类的结构明显看出来是数据结构中树的原型,用链表表示树的方法多种多样,这里用到的是孩子兄弟表示法。

10)protocols 

这里特意用这个名字是为了方便说明objectivc的协议,如果用面向对象的统一定义解释的话,这个指针是用来实现接口的,在c++中叫纯虚对象。

11)gc_object_type

 类方法和类变量从那而来的,这就是答案。


© 著作权归作者所有

gaoios
粉丝 4
博文 9
码字总数 4887
作品 0
苏州
私信 提问
成员变量这样的概念在不面向对象的语言里,怎样实现最优雅?

其实是最近在学习用GO写一个后台服务。 想把之前的一个服务重新写一遍, 之前一个请求进来,会new一个对象。然后对这个对象进行操作。 在类里边,可以定义成员变量,被所有的成员函数共享。有...

maxio-yu
2018/11/15
66
2
c++类模板,调用结构体模板出错!!

c++类模板,调用结构体模板出错!! Severity Code Description Project File Line Error LNK1120 3 unresolved externals Test C:\Users\Sar.Kerson\Desktop\Test1\Test\Debug\Test.exe 1 ......

ququyij
2016/07/06
205
1
C++结构体模板的使用

主要是返回时需要相当与返回的是结构体模板类型,我不知道怎么处理。

lws123253
2015/09/07
1K
1
object_getClass(obj)与[obj class]的区别在Object-C的类型结构中

在Object-C的类型结构中,有几个比较重要的概念:Object(实例),Class(类),Metaclass(元类),Rootclass(根类),Rootclass‘s metaclass(根元类),且这些都是对象。因此标题中的“obj”...

小春0618
2016/05/08
25
0
iOS开发小结(二):对象系统基础

Jason Lee @ 杭州 博客:http://blog.csdn.net/jasonblog 微博:http://weibo.com/jasonmblog [Outline] 1. id和Class 2. 动态地操作类 3. 实例化 [1. id和Class] ------------------------......

迷途d书童
2012/03/05
485
0

没有更多内容

加载失败,请刷新页面

加载更多

利用mybatis generator生成实体类、Mapper接口以及对应的XML文件

项目中通常会遇到数据的持久化,如果是采用mybatis的orm,就会涉及到生成xml的问题,刚好mybatis官网提供了这么个插件MyBatis Generator,效果简直是棒呆。 1. 首先需要在build.gradle文件中...

啊哈关关
今天
2
0
SpringSocial相关的知识点

使用SprigSocial开发第三方登录 核心类 ServiceProvider(AbstractOauth2ServiceProvider):主要负责实现server提供商(例如QQ,微信等共有的东西),默认实现类是AbstractOauth2ServiceProvider...

chendom
今天
4
0
Java并发之AQS详解

一、概述   谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronizer(AQS)!   类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源...

群星纪元
昨天
4
0
Fabric-sdk-java最新教程

Fabric Java SDK是Fabric区块链官方提供的用于Java应用开发的SDK,全称为Fabric-sdk-java,网上可用资料不多,本文列出了精心整理的针对Fabric Java SDK的最新精选教程。 如果希望快速掌握F...

汇智网教程
昨天
3
0
react 子组件监听props 变化

componentWillReceiveProps //已经被废弃 getDerivedStateFromProps// 推荐使用//如果条件不存在必须要返回null static getDerivedStateFromProps(props, current_stat...

一箭落旄头
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部