2

私は、NSTableView曲のタイトルでいっぱいのを持っています。

曲はアーティストごとに並べられているので、アーティスト名を行表示で表示できます。

ここに画像の説明を入力してください


コード

これまでは、テーブルデータを繰り返し処理し、アーティストを手動で配列に追加する必要がありました。

NSMutableArray *songsAndArtists = [NSMutableArray array];

Artist *artist;
for (Song *song in self.songs) {
    if (artist != song.artist) {
        artist = song.artist;
        [songsAndArtists addObject:artist];
    }

    [songsAndArtists addObject:song];
}

1'000〜5'000の曲がある場合、これは非常に遅くなる可能性があります。
このプロセスをどのようにスピードアップできるか、私は本当に理解していません。

誰かが実行時にこれを計算する方法を知っていますか?


編集

私が何を意味するのかを明確にしようと思います:

NSTableViewグループ行をサポートします。テーブルビューには、CoreDataのすべての曲が表示されます。上で追加した印刷画面のように、グループ行を使用して曲のアーティストを表示したいと思います。

これを行うには、アーティスト、その曲、次のアーティストなどの配列を提供する必要があります。

上記のコードはアーティストを挿入する方法を示していますが、かなり時間のかかるプロセスです。

だから私の質問、どうすればこれをスピードアップできますか?


ヒント

nielsbotやFeloneousCatが提案したように、すべてのアーティストを繰り返すことは私にはうまくいきません。

ユーザーには、ライブラリを検索するオプションもあります。したがって、すべての曲が実際にリストに表示されるわけではありません。


解決

問題が何であったかをお知らせください。

NSString問題は、以前のバージョンで実際に比較したことです。
かなり愚かな過ち...

0.1秒以内で完了します。これはすばらしいことです。

tableData = [self addGroupRowsToArray:[self allSongs] withKeyPath:@"artist"];

- (NSArray *)addGroupRowsToArray:(NSArray *)array withKeyPath:(NSString *)keyPath {
    NSMutableArray *mixedArray = [NSMutableArray array];

    id groupRowItem;
    for (id arrayItem in array) {
        if (groupRowItem != [arrayItem valueForKeyPath:keyPath]) {
            groupRowItem = [arrayItem valueForKeyPath:keyPath];
            [mixedArray addObject:groupRowItem];
        }

        [mixedArray addObject:arrayItem];
    }

    return mixedArray;
}
4

3 に答える 3

3

これは速いですか?

-(NSArray*)songsAndArtists:(NSArray*)allArtists
{
    NSMutableArray * result = [ NSMutableArray array ] ;
    for( Artist * artist in allArtists )
    {
        [ result addObject:artist ] ;
        [ result addObjectsFromArray:artist.songs ] ;
    }
    return result ;
}

Core Dataから「すべてのアーティスト」を取得している場合は、曲の関係にあるオブジェクトをプリフェッチするように指示できます。これにより、処理がさらに高速化されます。

-(NSArray*)allArtists
{
    NSFetchRequest * request = [ NSFetchRequest fetchRequestWithEntityName:@"Artist" ] ;
    [ request setRelationshipKeyPathsForPrefetching:@[ @"songs" ] ] ;
    ...
    return results ;
}
于 2013-01-04T21:20:39.737 に答える
3

それでは、バックアップして、あなたが本当に持っているものを見てみましょう。あなたはすでにあなたが歌に住むのに必要なすべての情報を持っています。なぜあなたは本質的に、単にアーティストを解き放つためにそれを複製しているのですか?

次の曲(曲/アーティスト)がある場合は、このように考えてください

(0)    "Death Eater", "Raging Machine Code"
(1)    "Interrupt",   "Raging Machine Code"
(2)    "Panic",       "Times Square Revolution"
(3)    "New Years",   "Times Square Revolution"
(4)    "Toast",       "Ed & Billy's Time Machine"
(5)    "Surge",       "Quiet Cat"
(6)    "Surveil",     "Quiet Cat"

この写真の何が問題になっていますか?同じ情報が重複しています。理想的には、次のようなものが必要です。

"Raging Machine Code"     -> has an  array that contains
                             "Death Eater"
                             "Interrupt"
"Times Square Revolution" -> has an array that contains
                             "Panic"
                             "New Years"
"Ed & Billy's Time Machine" -> array that contains
                             "Toast"
"Quiet Cat"               -> array that contains
                             "Surge"
                             "Surveil"

UITableViewの場合、これにより作業が簡単になります。セクション数(4)と、セクションごとに曲数を指定します。セルを生成するために、セクションと行を通知するNSIndexPathを取得します(セクションはアーティストであり、行はそのアーティストの曲です)。

NSTableViewはそれを行いません。それは私たちに列を与えます。ただし、フロントエンド(つまり曲リスト)で作業を行うと、人生が美しく速く(または少なくとも速く)なることを保証できます。重要なのは、アーティストごとの曲数を事前に計算して保存することです。

したがって、行5を表示するように求められたとします。「RagingMachine Code」は0〜2(アーティスト、曲、曲)です。「タイムズスクエアレボリューション」は3-5です。ああ!最後の曲は5曲なので「お正月」を表示します!

別の行を試してみてください。行6を表示するとします。「Raging...」は0〜2、「Times ...」は3〜5、「Ed&Billy's」は6〜7です。ビンゴ、アーティスト「Ed&Billy'sTimeMachine」を展示する必要があります!

アイデアは、実際にデータを表示する前に、この事前作業の多くを実行することです。アーティストをループする方が、すべての曲をループするよりもはるかに高速です。さらに、今は単純な計算をしているだけです。物を動かす必要はありません。

データの保存方法が成功と失敗の違いを意味する場合があります。「データ構造を再定義」する必要があることに気付いたときはいつでも、それは通常、データ構造に欠陥があることを意味します。それは単純かもしれませんが、より多くの労力を引き起こします。

うまくいけば、これが役に立ち、「TLTR」になることはありませんでした(読むには長すぎます)。

于 2013-01-04T21:26:09.797 に答える
3

さて、私はあなたの問題を再現しようとしました。どこからデータを取得するのかわからないので、パフォーマンステストのためだけに偽造しました。また、iPod 4genでコードをテストしましたが、遅れることなく動作します。(50000行のいずれかを試しましたが、開始時にのみハングし、その後完全に機能しました)

一般的に、私のアプローチはデータ構造に関してあなたのアプローチとは異なります。だからあなたは配列を使い、私は辞書を使います。それでも、配列を使用した場合、とにかく問題はないはずだと思います。多分私はあなたが尋ねたことを間違っていますか?

それでも、私のアプローチは検索が機能するのに適しているようです(私はそれを実装しようとするとあまりにも面倒でした)。実際、検索が行われるようになったため、もちろん曲を検索する必要がない限り、曲をチェックせずにセクション全体を除外することができます。とにかく、これにより柔軟性が高まります。

ここにリンクがあります:https ://github.com/igorpakushin/BigList

ここにいくつかのフィードバックを喜んでいたします、ありがとう

よろしく、イゴール

于 2013-01-12T00:11:10.313 に答える