美文网首页iOS技术专题iOS 开发 iOS开发
iOS RunTime之五:Category不能动态添加成员变量

iOS RunTime之五:Category不能动态添加成员变量

作者: s_在路上 | 来源:发表于2016-09-21 20:34 被阅读1221次

面试题:为什么Category中不能动态添加成员变量?

解答:

很多人在面试的时候都会被问到Category,既然允许用Category给类增加方法和属性,那为什么不允许增加成员变量?

Objective-C提供的runtime函数中,确实有一个class_addIvar()函数用于给类添加成员变量,但是阅读过苹果的官方文档的人应该会看到:

This function may only be called after objc_allocateClassPair and before objc_registerClassPair. Adding an instance variable to an existing class is not supported.

大概的意思说,这个函数只能在“构建一个类的过程中”调用。当编译你的类的时候,编译器生成了一个实例变量内存布局(ivar layout),来告诉运行时去那里访问你的类的实例变量们,一旦完成类定义,就不能再添加成员变量了。经过编译的类在程序启动后就被runtime加载,没有机会调用addIvar。程序在运行时动态构建的类需要在调用objc_registerClassPair之后才可以被使用,同样没有机会再添加成员变量。

Paste_Image.png

从运行结果中看出,你不能为一个类动态的添加成员变量,可以给类动态增加方法和属性。

因为方法和属性并不“属于”类实例,而成员变量“属于”类实例。我们所说的“类实例”概念,指的是一块内存区域,包含了isa指针和所有的成员变量。所以假如允许动态修改类成员变量布局,已经创建出的类实例就不符合类定义了,变成了无效对象。但方法定义是在objc_class中管理的,不管如何增删类方法,都不影响类实例的内存布局,已经创建出的类实例仍然可正常使用。

同理:

Paste_Image.png

某一个类的分类是在runTime时,被动态的添加到类的结构中。
想了解分类是如何加载的请看iOS RunTime之六:Category
如果有觉得上述我讲的不对的地方欢迎指出,大家多多交流沟通。

相关文章

网友评论

  • KA_STEM:“因为方法和属性并不“属于”类实例,而成员变量“属于”类实例。我们所说的“类实例”概念,指的是一块内存区域,包含了isa指针和所有的成员变量。所以假如允许动态修改类成员变量布局,已经创建出的类实例就不符合类定义了,变成了无效对象。但方法定义是在objc_class中管理的” ,变量也同样是objc_class来管理的,这解释的有点...
  • 奋斗的蝼蚁:作者能否把你的demo 共享出来,好研究下 谢谢

本文标题:iOS RunTime之五:Category不能动态添加成员变量

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