常见面试题:介绍一下分类,能用分类做什么?内部是如何实现的?它为什么会覆盖掉原来的方法?

深入了解Category

我们都知道OC代码执行时会先转成C\C++代码,OC对象转成对应的结构体; Category对应的结构体我们可以通过将分类的.m文件转成c++文件查看: xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc LZPerson+text.m 即可生成对应的.cpp文件; 在.cpp文件中搜索Category_t可以看到Category对应的结构体:

struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods;
const struct _method_list_t *class_methods;
const struct _protocol_list_t *protocols;
const struct _prop_list_t *properties;
};
复制代码

通过观察结构体我们可以发现分类对应的结构体中有存储实例方法的列表、存储类方法的列表、存储协议的和属性的列表。 到此可知面试题部分答案:

分类一般用来动态的为已经存在的类扩展新的方法。 分类中可以添加实例方法、类方法、属性、协议。但是不能添加成员变量。 添加属性的话只会生成set、get方法的声明不会实现也不会生成下划线成员变量。

如何‘覆盖’了原来的方法?

首先我们得知道:方法的调用就是消息的发送,如果调用实例方法,就是通过isa去类对象中查找对应的方法,如果调用类方法、就是通过isa去元类对象中查找对应的方法。

但是加入分类后通过isa去对应类或元类中查找时却能查到分类中写的方法!

所以我们可以得知:系统是在运行时把分类中的信息整合到了原来的类中!

到底推测是否正确以及如何整合,我们可以通过探究运行时的源码来分析。 源码下载地址:https://opensource.apple.com/tarballs/ 搜索objc4下载最新源码。

这里不张贴源码代码,只是把一步步的入口写出来,有兴趣的可根据以下的步骤去研读源码。

打开源码后首先找到Runtime的入口文件objc-os.mm然后找到初始化方法-objc_init(void)
->map_images()//镜像加载
->map_images_nolock()
->_read_images
->下滑找到//Discover categories
->remethodizeClass//重置类的方法
->attachCategories//绑定分类
->attachLists
->最核心的函数memmove和memcopy
复制代码

memmove:将原来类中的信息列表在内存中向后移动,移动的大小就是分类中的信息所占大小 memcopy:将分类中的信息复制到上一步移动出来的空间。

通过源码分析可知:系统是在运行时将分类中对应的实例方法、类方法等插入到了原来类或元类的方法列表中,且是在列表的前边!所以,方法调用时通过isa去对应的类或元类的列表中查找对应的方法时先查到的是分类中的方法!查到后就直接调用不在继续查找。这即是’覆盖’的本质!

存在多个分类,调用谁?

当有多个分类时,会调用哪个分类中的方法呢?

这个是与编译顺序有关,最后编译的分类中对应的信息会在整合在类或元类对应列表的最前边。所以是调用最后编译的分类中的方法!可以查看Build Phases ->Complie Source 中的编译顺序!

转载于:https://juejin.im/post/5b173d90f265da6e0245fc67

Category为什么会覆盖原来类中的方法?相关推荐

  1. python装饰器类-Python 装饰器装饰类中的方法

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  2. python装饰器实例-基于Python 装饰器装饰类中的方法实例

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] categ ...

  3. ViewController类中得方法和属性的用途

    ViewController类中得方法和属性的用途 1. wantsFullScreenLayout 只要在UIViewController上设置wantsFullScreenLayout=true ...

  4. kotlin调用类中的方法_一种轻松的方法来测试Kotlin中令人沮丧的静态方法调用

    kotlin调用类中的方法 by Oleksii Fedorov 通过Oleksii Fedorov 一种轻松的方法来测试Kotlin中令人沮丧的静态方法调用 (A stress-free way t ...

  5. Python类中公开方法、私有方法和特殊方法的继承原理

    在Python中,对象的私有成员在类外部.派生类或程序中无法直接访问,但是可以通过"对象名._类名__私有成员名"这样一种特殊的形式来访问. 基类的构造方法和公开方法可以在类的外部 ...

  6. python---方法解析顺序MRO(Method Resolution Order)<以及解决类中super方法>

    python---方法解析顺序MRO(Method Resolution Order)<以及解决类中super方法> 参考文章: (1)python---方法解析顺序MRO(Method ...

  7. Spring - 同一个类中的方法互相调用,注解失效问题的分析和解决(转)

    Spring - 同一个类中的方法互相调用,注解失效问题的分析和解决(转) 参考文章: (1)Spring - 同一个类中的方法互相调用,注解失效问题的分析和解决(转) (2)https://www. ...

  8. python buildin 中的一些类中为什么方法的内容都是pass?

    python buildin 中的一些类中为什么方法的内容都是pass? 文章目录: 一.看到的一些方法的定义都是pass 二.如何查看Python的源代码 python 的源代码是用C语言写的 一. ...

  9. 后盾网lavarel视频项目---2、phpstorm显示类中的方法快捷键

    后盾网lavarel视频项目---2.phpstorm显示类中的方法快捷键 一.总结 一句话总结: ctrl + f12 1.npm安装js插件? npm install hdjs 2.phpstor ...

  10. Java中divide用法_java的BIgInteger类中divideAndRemainder方法怎么用?

    展开全部 Java的BigInteger类中e68a8462616964757a686964616f31333433633436divideAndRemainder方法的用法是,先建一个BigInte ...

最新文章

  1. kafka高可用(集群)
  2. 关于源代码管理的10 个问题
  3. win10共享打印机怎么设置_小编为你叙述 win10系统网络共享理光打印机的设置方法的技巧介绍 -win10使用教程...
  4. 多目标遗传优化算法nsga2求解复杂约束问题【python源码实现,实数编码】
  5. Scaffolding Template on Asp.Net Core Razor Page
  6. 使用 Python 解数学方程
  7. 使用range()以相反的顺序打印列表?
  8. c语言基础代码_全国计算机二级等级考试:C语言二级考试有多难?不看不知道...
  9. php网站整合ck播放器,CKplayer 整合播放M3U8视频
  10. 使用 Transmission 制作种子命令
  11. 北京市小牛电动车选购指南
  12. bzoj5369 [Pkusc2018]最大前缀和(状压dp)
  13. 【图文并茂】U盘重装Win10方法教程
  14. php培训班学多久,学php最快要多久? 学习路线?要不要报培训班?
  15. 光模块简介、结构介绍及分类详解
  16. java获取时分秒毫秒_Calendar获取年月日时分秒毫秒
  17. csvn-httpd启动报AH00094错解决办法
  18. 软通动力-Java初级
  19. 迷你计算机工作站,这到底是什么 迄今最mini的工作站即将发售
  20. 高数(下)——平面及其方程

热门文章

  1. Flutter DecoratedBox装饰容器
  2. MDN - 字符串API笔记
  3. PHPExcel存放多个sheet报错: Invalid parameters passed.
  4. XAMPP端口更改后 httpd-vhosts.conf 文件配置
  5. .doc文件标题的使用
  6. PHP将图片转换成base64编码,hash函数
  7. Yii Framework2.0开发教程(6)数据库mysql--ActiveRecord
  8. OFFICE技术讲座:标点压缩是各大OFFICE软件差异关键,总体考量有哪些
  9. maven指定JDK
  10. Eclipse中修改项目的文本字符集编码