面试题答案
一键面试1. weak(弱引用)和strong(强引用)在内存管理方面的不同
- 引用计数影响:
- strong:当一个对象被
strong
指针指向时,对象的引用计数会增加。只要有至少一个strong
指针指向该对象,该对象就不会被释放。例如:
- strong:当一个对象被
NSObject *strongObject = [[NSObject alloc] init];
// 此时对象的引用计数至少为1
- weak:
weak
指针指向对象时,不会增加对象的引用计数。当对象的引用计数变为0并被释放时,指向它的所有weak
指针会自动被设置为nil
,从而避免野指针。例如:
NSObject *strongObject = [[NSObject alloc] init];
__weak NSObject *weakObject = strongObject;
strongObject = nil;
// 此时原来的对象引用计数为0,被释放,weakObject自动变为nil
- 对象生命周期:
- strong:
strong
指针能够维持对象的生命周期,只要有strong
指针存在,对象就不会被释放。这有助于确保对象在需要使用时一直可用。 - weak:
weak
指针不影响对象的生命周期,对象的释放与否取决于strong
指针的情况。weak
指针主要用于解决循环引用问题以及创建一种临时性的、不影响对象生命周期的引用。
- strong:
2. 适合使用weak的场景
- 解决循环引用:在视图控制器之间的父子关系或者视图之间的父子关系中,如果使用
strong
引用,很容易形成循环引用。例如,一个视图控制器ViewControllerA
持有一个子视图SubView
,而SubView
又持有ViewControllerA
,这就会导致循环引用。此时,在SubView
中使用weak
引用ViewControllerA
可以解决这个问题。
// ViewControllerA.m
#import "ViewControllerA.h"
#import "SubView.h"
@interface ViewControllerA ()
@property (nonatomic, strong) SubView *subView;
@end
@implementation ViewControllerA
- (void)viewDidLoad {
[super viewDidLoad];
self.subView = [[SubView alloc] initWithFrame:self.view.bounds];
self.subView.viewController = self;
[self.view addSubview:self.subView];
}
@end
// SubView.h
#import <UIKit/UIKit.h>
#import "ViewControllerA.h"
@interface SubView : UIView
@property (nonatomic, weak) ViewControllerA *viewController;
@end
// SubView.m
#import "SubView.h"
@implementation SubView
@end
- 监听者模式:当一个对象作为监听者,监听另一个对象的某些事件时,监听者对象对被监听对象使用
weak
引用。比如,Observer
对象监听Observable
对象的状态变化,Observer
持有weak
引用Observable
,这样Observable
的释放不会受到Observer
的影响。
3. 适合使用strong的场景
- 对象所有权明确:当一个对象对另一个对象拥有明确的所有权,并且需要确保该对象在其生命周期内一直存在时,使用
strong
引用。例如,一个Person
类持有一个Car
类的实例,Person
对Car
有所有权,在Person
的生命周期内,Car
应该一直存在。
@interface Car : NSObject
@end
@implementation Car
@end
@interface Person : NSObject
@property (nonatomic, strong) Car *car;
@end
@implementation Person
@end
- 需要长期持有对象:在数据模型或者单例模式等场景下,对象需要被长期持有并在应用的不同部分使用,此时使用
strong
引用。例如,一个管理用户信息的单例类UserManager
,应用的各个部分都可能需要访问该单例对象,所以使用strong
引用确保其一直存在。
@interface UserManager : NSObject
+ (instancetype)sharedManager;
@end
@implementation UserManager
+ (instancetype)sharedManager {
static UserManager *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}
@end
在其他类中使用时:
@interface SomeClass : NSObject
@property (nonatomic, strong) UserManager *userManager;
@end
@implementation SomeClass
- (void)someMethod {
self.userManager = [UserManager sharedManager];
}
@end