面试题答案
一键面试优化事件处理避免卡顿
- 合理设计视图层次:
- 减少不必要的视图嵌套,复杂视图尽量拆分成多个简单视图。例如,如果有一个包含很多子视图的大容器视图,若其中某些子视图可以独立成组,就将它们分别封装成新的视图,这样在响应事件时可以减少遍历视图树的开销。
- 延迟加载与懒加载:
- 对于一些不马上需要的用户交互元素,采用懒加载方式。比如,一个应用中有多个分页的表单,其中后几页的表单元素可以在用户切换到相应页面时再加载并初始化事件处理,而不是一开始就全部加载并设置事件处理。
- 优化事件处理逻辑:
- 多个按钮点击事件:
- 使用target - action模式:在视图控制器中,为每个按钮设置相同的target为视图控制器自身,不同的action方法。例如:
- 多个按钮点击事件:
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
[button1 addTarget:self action:@selector(button1Tapped) forControlEvents:UIControlEventTouchUpInside];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
[button2 addTarget:self action:@selector(button2Tapped) forControlEvents:UIControlEventTouchUpInside];
- **使用事件代理**:如果多个按钮属于同一类型,且处理逻辑有相似之处,可以通过设置代理来处理。先定义一个协议,视图控制器遵循该协议,在按钮初始化时设置代理为视图控制器。例如:
@protocol ButtonClickDelegate <NSObject>
- (void)buttonClicked:(UIButton *)button;
@end
@interface ViewController : UIViewController <ButtonClickDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
button1.delegate = self;
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
button2.delegate = self;
}
- (void)buttonClicked:(UIButton *)button {
if (button == button1) {
// 处理button1点击逻辑
} else if (button == button2) {
// 处理button2点击逻辑
}
}
@end
- 使用GCD处理异步交互操作:
- 主线程与子线程分工:主线程主要负责处理UI更新,将耗时的操作放到子线程执行。例如,当按钮点击后需要从网络获取数据并更新UI时,代码如下:
- (void)buttonTapped {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// 异步获取数据,例如网络请求
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://example.com/api"]];
// 回到主线程更新UI
dispatch_async(dispatch_get_main_queue(), ^{
if (data) {
// 更新UI,例如设置图片、文字等
self.imageView.image = [UIImage imageWithData:data];
}
});
});
}
- **使用dispatch_group进行任务组合**:如果有多个异步任务,且需要在所有任务完成后再执行某些操作(比如更新UI),可以使用dispatch_group。例如:
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 第一个异步任务
dispatch_group_async(group, queue, ^{
// 模拟耗时操作
sleep(2);
NSLog(@"Task 1 completed");
});
// 第二个异步任务
dispatch_group_async(group, queue, ^{
// 模拟耗时操作
sleep(3);
NSLog(@"Task 2 completed");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"All tasks completed, update UI");
// 更新UI操作
self.label.text = @"All tasks done";
});
-
优化数据存储与读取:
- 对于与用户交互元素相关的数据,采用高效的数据结构存储。例如,如果按钮点击需要获取特定的配置信息,使用字典(NSDictionary)来存储配置数据,通过键值对快速查找,避免使用线性查找的数组等低效结构。
-
使用CADisplayLink进行动画相关优化:
- 如果用户交互涉及动画,使用CADisplayLink来控制动画节奏。比如,在按钮点击后触发一个动画,通过CADisplayLink设置合适的帧率,避免因动画过于频繁导致卡顿。例如:
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animate)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
- (void)animate {
// 动画逻辑,例如更新视图位置等
self.view.frame = CGRectMake(self.view.frame.origin.x + 1, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
}