面试题答案
一键面试1. 同时使用 __block
和 __weak
的情况及原理
- 在Objective-C中,
__block
用于解决在block内部修改外部变量的问题,它会将变量包装成一个结构体,使得block可以修改其值。而__weak
用于创建一个弱引用,不会增加对象的引用计数。 - 当同时使用
__block
和__weak
修饰一个对象时,__block
使该对象可以在block内部被修改,__weak
确保该对象不会因为被block捕获而导致循环引用。例如:
__block __weak id weakObj = someObject;
someBlock = ^{
id strongObj = weakObj;
if (strongObj) {
// 使用 strongObj
}
};
这里 __block
允许在block内部对 weakObj
进行操作(虽然通常在这种场景下很少有修改 weakObj
本身的需求),__weak
防止 block
对对象产生强引用。
2. 可能带来的内存管理问题
- 对象提前释放风险:由于是弱引用,如果在block执行之前,被弱引用的对象已经释放,那么在block内部访问
weakObj
时,它可能为nil
。例如上述代码中,如果在someBlock
执行前someObject
被释放,weakObj
就为nil
,访问strongObj
可能导致空指针异常(虽然通过if (strongObj)
判断可以避免崩溃)。
3. 解决方案
- 使用强引用临时变量:如上述代码中,在block内部先将
weakObj
赋值给一个强引用的临时变量strongObj
,并进行nil
检查。这样在strongObj
的作用域内,对象不会被释放,保证了在block执行期间对象的存活。例如:
__block __weak id weakObj = someObject;
someBlock = ^{
id strongObj = weakObj;
if (strongObj) {
// 使用 strongObj
}
};
- 合理设计对象生命周期:确保在block可能执行的时间段内,被引用的对象有合理的生命周期管理,避免对象过早释放。例如可以在持有block的对象中,保证相关对象在block执行完毕后再释放。