面试题答案
一键面试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
强引用CustomView
,CustomView
使用weak
弱引用ViewController
来避免循环引用。