MST

星途 面试题库

面试题:Objective-C中循环引用的常见场景有哪些

请举例说明Objective-C中可能出现循环引用的常见场景,并简要解释为何会形成循环引用。
49.6万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

常见场景及原因

  1. 代理(Delegate)设置不当
    • 场景:在视图控制器A中设置视图控制器B为代理,同时视图控制器B又持有视图控制器A的引用。例如,A是一个主视图控制器,B是一个弹出的子视图控制器,B中有一个操作完成后需要通知A,于是A设置B的代理为自己,而B在某些情况下又强引用了A。
    • 原因:A对B有强引用(可能是通过属性持有B的实例),B对A作为代理也有强引用(如果代理属性声明为strong而非weak),这样就形成了A -> B -> A的强引用环,导致循环引用。
  2. NSTimer
    • 场景:在一个视图控制器中创建一个NSTimer,并将其添加到当前的运行循环中,NSTimer的目标设置为该视图控制器本身。比如在视图控制器的viewDidLoad方法中:self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateUI) userInfo:nil repeats:YES];
    • 原因NSTimer对其目标(这里是视图控制器)有强引用,而视图控制器又持有NSTimer实例(通过self.timer),从而形成视图控制器 -> NSTimer -> 视图控制器的强引用环,造成循环引用。
  3. Block
    • 场景:在一个对象的方法中定义一个block,block中使用了该对象的属性,而这个block又被该对象持有。例如:
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@end

@implementation MyClass
- (void)doSomething {
    self.block = ^{
        NSLog(@"%@", self.name);
    };
    self.block();
}
@end
- **原因**:对象持有block,block由于捕获了`self`(通过访问`self.name`)对对象有强引用,形成对象 -> block -> 对象的强引用环,引发循环引用。