博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS Category 和 Extention 的本质区别【面试必备】
阅读量:5982 次
发布时间:2019-06-20

本文共 990 字,大约阅读时间需要 3 分钟。

为什么category 不能添加属性,而Extention能添加?

这个问题从几个方面来解释下:

  • 什么是OC中的属性?

    属性,是某个对象持有的特性。一般(注意这里的一般)都是在编译期编译的时候,对象持有的属性会决定对象的内存布局,编译期过后,在运行期,一般很少更改这个布局,因为运行期更改已经定好的布局,不仅会带来一系列的内存问题,而且内存开销会很大。

    打个比方:就像是买房摇号有几千人排队呢,你后来的去插队,那么就会导致后面的人的位置发生变化,并且还会激起民愤!

  • 作用时期

    Extension 是在编译期决议(起作用)

    Category 是在 运行期决议(起作用)

  • 作用原理

    Extention是类的一部分,能决定类的内存布局,跟对象的生命周期一致,对象生成Extention添加的属性有效,对象释放,属性释放;

    Category并不是真正的类,他的作用是动态的给类添加方法,不改变类的内存布局。

    那么,现在再来看这个问题,是不是很好解释了呢

    因为Extention是在编译期期决议,那么他就能决定类对象的内存布局,就能正常的给类添加属性。
    而Category是在运行期决议的,动态的更改类,如果添加了属性,那就会更改内存布局;而内存布局是在编译期就定好了的,运行期更改内存布局会引发不必要的内存风险并且会有很大的内存开销。所以,苹果为了避免这种情况,禁止类别动态添加属性更改内存布局。

    但是,为什么 runtime 动态添加属性呢?

    那是因为 runtime关联的属性,并不是在真正的属性的位置添加的,而是在 AssociationsManager 管理的一个静态区内存 AssociationsHashMap 来存储关联对象的。所有用runtime 动态关联的属性都存在这个全局的map里面。map的key就是关联的对象的内存地址,而这个map的value又是另外一个AssociationsHashMap,里面保存了关联对象的键值对。

    那如何销毁RunTime关联的属性呢?

    runtime的销毁对象函数objc_destructInstance里面会判断这个对象有没有关联对象,如果有,会调用_object_remove_assocations做关联对象的清理工作。

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

你可能感兴趣的文章
那些年命途多舛的千千静听,归来能否再现当年荣光?
查看>>
Scrapy框架的使用之Scrapy对接Splash
查看>>
ECMAScript Decorators---装饰器
查看>>
Android组件化专题 - 组件化配置
查看>>
Kotlin 之高阶函数与Lambda表达式与闭包
查看>>
【填坑日记】<transition-group> children must be keyed: <ElTag>
查看>>
Sketch原创插件: Name Organizer
查看>>
C++ string 详解
查看>>
小白入门学习Python,值得你重视的那些事儿
查看>>
859. Buddy Strings
查看>>
thinkphp源码分析(二)—入口篇
查看>>
Netty走读笔记-1-NIO基础
查看>>
宜人贷蜂巢API网关技术解密之Netty使用实践
查看>>
【跃迁之路】【730天】程序员高效学习方法论探索系列(实验阶段487-2019.2.20)...
查看>>
SAP云平台对Kubernetes的支持
查看>>
Travis CI 部署遇到的问题
查看>>
PAT A1119 前序遍历后续遍历不唯一生成
查看>>
Stream流与Lambda表达式(五) Stream BaseStream AutoCloseable源码解读
查看>>
学习webpack4 - HTML处理
查看>>
Laravel核心解读--完结篇
查看>>