MST

星途 面试题库

面试题:Objective-C中strong和weak修饰符的主要区别是什么

在Objective-C中,strong和weak是常用的属性修饰符,请阐述它们在内存管理和对象引用关系上的主要区别,并举例说明在什么场景下会分别使用到这两种修饰符。
23.8万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

内存管理和对象引用关系区别

  1. strong
    • 内存管理:strong修饰符会对对象保持强引用。当一个对象被一个或多个strong指针引用时,该对象的引用计数会增加。只有当所有指向该对象的strong指针都被释放或重新指向其他对象时,对象的引用计数降为0,对象才会被系统回收,从内存中释放。
    • 对象引用关系:建立了强引用关系,意味着只要有strong指针指向对象,对象就不会被释放。
  2. weak
    • 内存管理:weak修饰符对对象保持弱引用,不会增加对象的引用计数。当对象的引用计数降为0并被释放时,所有指向该对象的weak指针会自动被设置为nil(避免野指针)。
    • 对象引用关系:弱引用不会阻止对象被释放,当对象被释放后,指向它的weak指针变为nil

使用场景举例

  1. strong
    • 场景:在视图控制器中,通常使用strong修饰视图属性。例如,一个视图控制器ViewController有一个UILabel属性:
    @interface ViewController : UIViewController
    @property (nonatomic, strong) UILabel *myLabel;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.myLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 50)];
        [self.view addSubview:self.myLabel];
    }
    @end
    
    • 解释:这里使用strong修饰myLabel,确保myLabel在视图控制器的生命周期内一直存在,因为视图控制器对myLabel保持强引用,防止在视图控制器使用myLabel时,myLabel被意外释放。
  2. weak
    • 场景:在解决视图控制器之间的循环引用问题时,通常使用weak。例如,有一个父视图控制器ParentViewController和一个子视图控制器ChildViewControllerParentViewController持有ChildViewController,同时ChildViewController需要反向引用ParentViewController。如果ChildViewControllerParentViewController使用strong,会形成循环引用。
    @interface ParentViewController : UIViewController
    @property (nonatomic, strong) ChildViewController *childVC;
    @end
    
    @interface ChildViewController : UIViewController
    @property (nonatomic, weak) ParentViewController *parentVC;
    @end
    
    @implementation ParentViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.childVC = [[ChildViewController alloc] init];
        self.childVC.parentVC = self;
        [self addChildViewController:self.childVC];
        [self.view addSubview:self.childVC.view];
    }
    @end
    
    • 解释ChildViewControllerParentViewController使用weak修饰,这样就打破了循环引用。当ParentViewController被释放时,ChildViewControllerparentVC属性会自动变为nil,避免了内存泄漏。