面试题小结整理

能否想编译后的类中添加实例变量,能否像运行时创建的类添加实例变量?为什么?

不能向编译后得到的类增加实例变量,能向运行时创建的类中添加实例变量

解释:

编译后的类已经注册在runtime中,类结构体中的objc_ivar_list实例变量的链表和instance_size实例变量的内存大小已经确定,runtime会调用class_setvarlayout或class_setWeaklvarLayout来处理strong,weak引用.所以不能向存在的类中添加实例变量

2.运行时创建的类是可以添加实例变量,调用class_addIvar函数.但是的在调用objc_allocateClassPair之后,objc_registerClassPair之前,原因同上.



为什么不使用__block就不能在Block内部修改外部的局部变量?

我们注意到Block实质被转换成了一个__main_block_impl_0的结构体实例,其中__main_block_impl_0结构体的成员包括局部变量val。在__main_block_impl_0结构体的构造方法中,val作为第三个参数传递进入。

但执行我们的Block时,通过block找到Block对应的方法执行部分__main_block_func_0,并把当前block作为参数传递到__main_block_func_0方法中。

那么,为什么这个时候不能给val进行赋值呢?

因为main函数中的局部变量val和函数__main_block_func_0不在同一个作用域中,调用过程中只是进行了值传递。当然,在上面代码中,我们可以通过指针来实现局部变量的修改。不过这是由于在调用__main_block_func_0时,main函数栈还没展开完成,变量val还在栈中。但是在很多情况下,block是作为参数传递以供后续回调执行的。通常在这些情况下,block被执行时,定义时所在的函数栈已经被展开,局部变量已经不在栈中了(block此时在哪里?),再用指针访问就……

所以,对于auto类型的局部变量,不允许block进行修改是合理的

你可能感兴趣的:(面试题小结整理)