2

バックグラウンド

  • NSOutlineViewTrainingGroupエンティティを表示するがあります。

  • 各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.自分のアプローチについて何を改善できますか?

4

1 に答える 1

1
  1. バックグラウンドスレッドで更新します(No. 2)
  2. ウィンドウのセクションでのユーザー入力をいつでも無効にして、読み込みメッセージを表示することができます。
  3. 簡単に言うと、すべてのコードを調べて、必要な呼び出し回数を最小限に抑え、不要な関数を呼び出さないようにしてください。また、別々のスレッドでいくつかの長期的な操作を実行し、アクションが終了したときに通知を受け取ることができるので、操作の進行中に他のことを処理できます。
于 2010-09-24T12:50:06.750 に答える