iOS总结面试题答案
1.__block修饰的变量为什么能在block里面能改变其值?
Block不允许修改外部变量的值,这里所说的外部变量的值,指的是栈中指针的内存地址。__block 所起到的作用就是只要观察到该变量被 block 所持有,就将“外部变量”在栈中的内存地址放到了堆中。进而在block内部也可以修改外部变量的值。
Block不允许修改外部变量的值,这里所说的外部变量的值,指的是栈中指针的内存地址。栈区是红灯区,堆区才是绿灯区
2.Category为什么不能直接添加属性?
这里我见了一个名为test的UIImageView的分类(类别):
@interface UIImageView (test)
Category在代码里添加成员变量是根本编译不过去的,而添加属性是可以编译通过的,如图:


⚠️也就是在Category添加的属性后,只会声明setter和getter方法,但是在.m文件并未实现setter和getter方法,所以会有黄色预警,如果调用该属性,也不会被赋值。最常见的解决方案就是用runtime手动实现setter和getter方法。

所以,总结,Category不能添加成员变量和属性?就可以有答案了,不能添加成员变量,可以添加属性,但是属性要手动实现setter和getter方法;可以添加实例方法,类方法,甚至可以实现协议,添加属性)但是(无法添加实例变量)
类的内存布局在编译时期就已经确定了,category是运行时才加载的,早已经确定了内存布局所以无法添加实例变量,如果添加实例变量就会破坏category的内部布局。反观扩展(extension),作用是为一个已知的类添加一些私有的信息,必须有这个类的源码,才能扩展,它是在编译器生效的,所以能直接为类添加属性或者实例变量。
1)category的方法并没有“完全替换掉”原来类已经有的方法,而是把扩展的方法放入到方法列表的前头,举个栗子(原来的方法列表,扩展的方法是<1,2,3>,会变成<1,2,3,a,b,c>。)
2)为什么平常所说的category的方法会“覆盖”掉原来类的同名方法,就是因为运行时在查找方法的时候是顺着方法列表的顺序查找的,而且只要一找到对应名字的方法,就会结束查找。
美团技术博客摘自这里,全面深层分析!