バックグラウンド
NSOutlineView
TrainingGroupエンティティを表示するがあります。各TrainingGroupは、ローカルマシン上のフォルダーを表します。
は、
NSOutlineView
フェッチNSTreeController
述語が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
コード
TrainingGroup.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モーダルプログレスバー
アプローチ
- 別のコンテキストでバックグラウンドスレッドでプロジェクト割り当てを実行します。
- 終了したら、標準のCoreDataマージをメインコンテキストに使用します。
- モーダルシートは、プロジェクトの割り当てが完了するまで、それ以降のアクティビティをブロックします。
いいもの
- ユーザーは、何が起こっているかについて即座にフィードバックを受け取ります。
- アプリは応答性を維持します。
悪い人
- 現在の割り当てが完了するまで、ユーザーは何もできません。
2非モーダルスピナー
アプローチ
- 別のコンテキストでバックグラウンドスレッドでプロジェクト割り当てを実行します。
- 終了したら、標準のCoreDataマージをメインコンテキストに使用します。
- トレーニンググループの横に進行状況スピナーを表示し、忙しいことを示します。
- 割り当てが完了すると、トレーニンググループがビューから消えます。
いいもの
- ユーザーは、最後のアクションが処理されている間に他のことを行うことができます
- アプリは応答性を維持します。ちょっと。下記参照。
悪い人
- テストでは、バックグラウンドコンテキストがメインコンテキストにマージされると、最大3秒のフリーズが発生しました。
- ユーザーが何か他のことをしている最中にビューが更新される可能性があり、これは煩わしいかもしれません。
- 元に戻すは実装が難しいでしょう。
3非表示
アプローチ
- 上記。ただし、トレーニンググループは割り当て時に削除され、割り当てが完了するまで「進行中」に設定されます。
良い点と悪い点
- 上記と同じですが、トレーニンググループの順序が予測可能である点が異なります。
- メインコンテキストにマージして戻すと、まだ大幅にフリーズします。
4パフォーマンスを向上させる
アプローチ
- コードをそのままにして、メインスレッドで実行します。
- パフォーマンスを向上させて、何千ものエントリがあっても、ビューが最大0.5秒だけフリーズするようにします
いいもの
- アプリは応答性を維持します。
- 元に戻すのは簡単です。
- アーキテクチャはシンプルなままです。
悪い人
- 私が理解しているように、Appleの推奨に反して、メインスレッドで集中的な処理を行うべきではありません
- 十分なパフォーマンスを得ることができますか?わからない。
私の質問
私が見る限り、上記のオプションはどれも理想的ではありません。
1.最適なオプションはどれですか?
2.他にオプションはありますか?
3.自分のアプローチについて何を改善できますか?