背景
我有一个
NSOutlineView
显示 TrainingGroup 实体的。每个 TrainingGroup 代表本地机器上的一个文件夹。
The
NSOutlineView
绑定到一个NSTreeController
带有 fetch 谓词的IsTrained == 0
每个 TrainingGroup 都可以分配给一个项目。
每个 TrainingGroup 都有许多 TrainingEntries 显示在该文件上工作的时间。
当 TrainingGroup 分配给一个项目时,
IsTrained
设置为YES
。在分配给项目时,所有后代也被分配给该项目,并且它们的
IsTrained
属性也设置为YES
。项目列绑定到
projectTopLevel
属性。
例子
整棵树看起来像这样:
Name Project IsTrained
Users nil NO
John nil NO
Documents nil NO
Acme Project Acme Project YES
Proposal.doc Acme Project YES
12:32-12:33 Acme Project YES
13:11-13:33 Acme Project YES
... etc
Budget.xls Acme Project YES
Big Co Project Big Co Project YES
Deadlines.txt Big Co Project YES
Spec.doc Big Co Project YES
New Project nil NO
StartingUp.doc nil NO
Personal Stuff Personal YES
MyTreehouse.doc Personal YES
Movies nil NO
Aliens.mov nil NO
StepMom.mov nil NO
而 NSOutlineView 只会看到这个:
Users nil NO
John nil NO
Documents nil NO
New Project nil NO
StartingUp.doc nil NO
Movies nil NO
Aliens.mov nil NO
StepMom.mov nil NO
如果您将电影分配给个人,则视图现在将如下所示:
Users nil NO
John nil NO
Documents nil NO
New Project nil NO
StartingUp.doc nil NO
代码
培训组.m
-(void)setProjectTopLevel:(JGProject *)projectToAssign {
[self setProjectForSelf:projectToAssign];
[self setProjectForChildren:projectToAssign];
}
-(void)setProjectForSelf:(JGProject *)projectToAssign {
[self setProject:projectToAssign];
}
-(void)setProjectForChildren:(JGProject *)projectToAssign {
for (TrainingGroup *thisTrainingGroup in [self descendants]) {
[thisTrainingGroup setProject:projectToAssign];
if(projectToAssign != nil) {
[thisTrainingGroup setIsTrainedValue:YES];
} else {
[thisTrainingGroup setIsTrainedValue:NO];
}
// Other code updating rules.
}
}
-(JGProject *)projectTopLevel {
return [self project];
}
-(NSSet *)untrainedChildren {
// Code that loops through all children returning those
// whose isTrained is NO. Omitted for brevity.
}
问题
正如您在上面看到的,我目前正在主线程上运行所有项目分配代码。
当每个文件夹下有数百个时间条目时,我的应用程序变得无响应。
可能的解决方案
1 模态进度条
该方法
- 在单独的上下文中在后台线程上运行项目分配。
- 完成后使用标准核心数据合并到主上下文中。
- 在项目分配完成之前,模式表会阻止任何进一步的活动。
好的
- 用户会立即获得有关正在发生的事情的反馈。
- 该应用程序保持响应。
坏的
- 在当前分配完成之前,用户不能做任何事情。
2 非模态微调器
该方法
- 在单独的上下文中在后台线程上运行项目分配。
- 完成后使用标准核心数据合并到主上下文中。
- 在训练组旁边显示进度微调器,表示它很忙。
- 完成分配后,培训组将从视图中消失。
好的
- 用户可以在处理他们的最后一个动作时做其他事情
- 该应用程序保持响应。有点。见下文。
坏的
- 在测试中,当背景上下文合并到主上下文中时,我看到最多冻结 3 秒。
- 视图可能会在用户执行其他操作时更新,这可能很烦人。
- 撤消将难以实施。
3 隐藏
该方法
- 以上,除了培训组在分配时被删除,并设置为“进行中”,直到分配完成。
好和坏
- 与上面相同,除了训练组的顺序仍然是可预测的。
- 合并回主要上下文时仍然大冻结。
4 提高性能
该方法
- 保持代码原样,在主线程上运行。
- 提高性能,即使有数千个条目,视图最多只能冻结半秒
好的
- 应用程序保持响应。
- 撤消仍然很容易。
- 建筑仍然很简单。
坏的
- 据我了解,违反 Apple 的建议 - 不应在主线程上进行密集处理
- 我能得到足够好的性能吗?未知。
我的问题
据我所知,以上选项都不是理想的。
1. 哪个是最好的选择?
2. 还有其他选择吗?
3. 我可以改进我的方法的哪些方面?