MST

星途 面试题库

面试题:Objective-C中__weak与__strong变量修饰符在循环引用场景下的应用

假设你正在开发一个iOS应用,遇到了视图控制器(ViewController)和其内部的一个自定义视图(CustomView)之间可能产生循环引用的情况。请阐述如何利用__weak和__strong修饰符来解决这个问题,并写出关键代码片段。
50.2万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. 原理阐述

在iOS开发中,视图控制器(ViewController)和自定义视图(CustomView)之间可能产生循环引用。一般来说,视图控制器会强引用自定义视图,即ViewController持有CustomView的强引用。如果CustomView反过来也强引用ViewController,就会形成循环引用。

使用__weak修饰符可以创建一个弱引用,弱引用不会增加对象的引用计数,当被引用的对象释放时,弱引用会自动被设置为nil,从而打破循环引用。而__strong修饰符就是常见的强引用,会增加对象的引用计数。

2. 关键代码片段

假设ViewController包含一个CustomView属性,并且CustomView有一个指向ViewController的属性:

// CustomView.h
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface CustomView : UIView

@property (nonatomic, weak) id viewController; // 使用__weak修饰符,避免循环引用

@end

NS_ASSUME_NONNULL_END
// ViewController.m
#import "ViewController.h"
#import "CustomView.h"

@interface ViewController ()

@property (nonatomic, strong) CustomView *customView; // 使用__strong修饰符,持有CustomView

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.customView = [[CustomView alloc] initWithFrame:self.view.bounds];
    self.customView.viewController = self;
    [self.view addSubview:self.customView];
}

@end

在上述代码中,ViewController使用__strong修饰符持有CustomView,而CustomView使用__weak修饰符持有ViewController,这样就避免了循环引用。

如果是Swift语言:

// CustomView.swift
import UIKit

class CustomView: UIView {
    weak var viewController: UIViewController? // 使用weak关键字,避免循环引用
}
// ViewController.swift
import UIKit

class ViewController: UIViewController {
    var customView: CustomView! // 默认是强引用
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        customView = CustomView(frame: view.bounds)
        customView.viewController = self
        view.addSubview(customView)
    }
}

在Swift中,同样ViewController强引用CustomViewCustomView使用weak弱引用ViewController来避免循环引用。