面试题答案
一键面试1. 设计状态基类
首先定义一个状态基类,其他具体状态类继承自该基类。
// 状态基类
@interface ResourceState : NSObject
// 处理状态变化时的操作
- (void)handleStateChange:(id)resource;
@end
@implementation ResourceState
- (void)handleStateChange:(id)resource {
// 基类中可以不实现具体逻辑,留给子类实现
}
@end
2. 定义具体状态类
分别实现“初始化”“加载中”“已加载”“错误”这四种状态。
// 初始化状态
@interface InitializingState : ResourceState
@end
@implementation InitializingState
- (void)handleStateChange:(id)resource {
// 这里可以进行资源创建相关操作,比如初始化数据结构等
NSLog(@"Resource is initializing.");
}
@end
// 加载中状态
@interface LoadingState : ResourceState
@end
@implementation LoadingState
- (void)handleStateChange:(id)resource {
// 处理加载中的逻辑,如显示加载指示器等
NSLog(@"Resource is loading.");
}
@end
// 已加载状态
@interface LoadedState : ResourceState
@end
@implementation LoadedState
- (void)handleStateChange:(id)resource {
// 可以在这里进行数据读取操作
NSLog(@"Resource is loaded.");
}
@end
// 错误状态
@interface ErrorState : ResourceState
@end
@implementation ErrorState
- (void)handleStateChange:(id)resource {
// 处理错误逻辑,如释放资源等
NSLog(@"Resource has an error.");
}
@end
3. 定义资源类
资源类持有当前状态,并提供状态切换方法。
@interface Resource : NSObject
@property (nonatomic, strong) ResourceState *currentState;
// 切换状态方法
- (void)changeState:(ResourceState *)newState;
@end
@implementation Resource
- (void)changeState:(ResourceState *)newState {
// 切换状态前,处理旧状态下可能需要的清理操作
[self.currentState handleStateChange:self];
self.currentState = newState;
// 切换状态后,执行新状态的相关操作
[self.currentState handleStateChange:self];
}
@end
4. 处理多线程资源竞争和内存管理
为了处理多线程资源竞争问题,使用 NSLock
或者 dispatch_queue
。这里以 dispatch_queue
为例。
@interface ResourceManager : NSObject
@property (nonatomic, strong) Resource *resource;
// 串行队列,用于处理资源相关操作,避免资源竞争
@property (nonatomic, strong) dispatch_queue_t resourceQueue;
+ (instancetype)sharedManager;
@end
@implementation ResourceManager
+ (instancetype)sharedManager {
static ResourceManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[ResourceManager alloc] init];
manager.resource = [[Resource alloc] init];
manager.resource.currentState = [[InitializingState alloc] init];
// 创建一个串行队列
manager.resourceQueue = dispatch_queue_create("com.example.resourceQueue", DISPATCH_QUEUE_SERIAL);
});
return manager;
}
// 在队列中安全地切换资源状态
- (void)safeChangeState:(ResourceState *)newState {
dispatch_async(self.resourceQueue, ^{
[self.resource changeState:newState];
});
}
@end
5. 内存管理
通过合理的对象生命周期管理来避免内存泄漏。在状态类和资源类的 dealloc
方法中释放相关资源。
// 例如在Resource类的dealloc方法中
@implementation Resource
- (void)dealloc {
// 释放可能持有的资源
self.currentState = nil;
}
@end
// 各个状态类也类似,释放各自持有的资源
@implementation InitializingState
- (void)dealloc {
// 释放初始化状态下持有的资源
}
@end
这样,通过上述设计方案,在保证状态模式正确运行的同时,利用 dispatch_queue
处理了多线程带来的资源竞争问题,并通过合理的对象生命周期管理做好了内存管理,避免了内存泄漏。