OC-category 为什么不能添加成员变量

以下的答案是百度的,仅做记录而已:

1. 利用运行时实际上也不是添加成员变量。已编译的类的内存布局是不变的,Class就是一个结构体,里面的成员不能改变。但是通过运行时可以将一个对象或基础类型变成指定Class对象的一个关联对象,他们两者的内存布局是分开的,与成员变量不同。

 

2.关联的并不是在指定Class上,而是指定的对象上,概念上有一定差别。
objc_setAssociatedObject()这个函数接收四个参数,第一个是需要关联的对象,第二个是索引的一个KEY,第三个是被关联对象,第四个是内存管理类型。
所以这里运行时会为某个对象设一个关联键值对,通过KEY可以找到对应的关联对象。
objc_getAssociatedObject(),接收关联对象和KEY提取出被关联对象。

 

3.Rumtime的话是黑魔法,滥用起来的话OC会变成JS,动态能力太强,什么都可以通过运行时来改。。但同时也让维护变得非常困难,就像交换方法这种,如果故意恶作剧在一些Foundation里交换了一些常用方法。。这就坑爹了。
Runloop的话如果不涉及优化的话也不是很常用,通常是通过添加观察者响应Runloop状态的回调从而进行一些操作,例如在Runloop空闲的时候扔一些任务给他做做。

 



APP开发更注重是是上层与业务打交道的逻辑。到需要优化的时候再考虑用这些黑魔法去实现。

 

4.OC是不能直接修改对象的结构体的成员变量属性,一般做法是先取出对象的结构体变量,修改该取出来的结构体变量里面的成员,再把结构体对象赋值给原来的结构体变量;这个就要弄清@property关键字了,在类中@property关键字会生成私有成员变量,和申明getter setter方法,但是在分类中只会声明getter和setter方法,不会生成成员变量;扩展: 如果在.m中手动实现了setter和getter方法,x-code就不会自动生成@synthesize,也就不会生成成员变量;点语法访问的是getter方法,对象的->调用才是访问的成员变量

 

5.如果我们真的需要给category增加属性的实现,需要借助于运行时的两个函数:

<em id="__mceDel">objc_setAssociatedObject
objc_getAssociatedObject

6.就category和extension的区别来看,我们可以推导出一个明显的事实,extension可以添加实例变量,而category是无法添加实例变量的(因为在运行期,对象的内存布局已经确定,如果添加实例变量就会破坏类的内部布局,这对编译型语言来说是灾难性的)</em>
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值