2

ローカル iOS デバイス上のすべてのアーティストと、各アーティストについて、そのアーティストが利用できる曲の数を取得しようとしています。

私は現在、すべてのアーティストをクエリし、各アーティストについてコレクション内のアイテム (曲) の数を数えることで、これを簡単な方法で行っています。

MPMediaQuery *query = [[MPMediaQuery alloc] init];
[query setGroupingType:MPMediaGroupingArtist];
NSArray *collections = [query collections];
for (MPMediaItemCollection *collection in collections)
{
    MPMediaItem *representativeItem = [collection representativeItem];
    int songs = [[collection items] count];
    // do stuff here with the number of songs for this artist
}

ただし、これはあまり効率的ではないようです。少なくとも、予想よりも遅いです。

数百人のアーティストが参加している iPhone 4 デバイスのデモでは、上記のコードの実行に約 7 秒かかりました。「コレクションアイテム」のカウントを取得する行をコメントアウトすると、時間が 1 秒に短縮されます。

それで、私が上でやっていることよりもアーティストの曲数を取得するためのより速い方法があるかどうか疑問に思っていますか?


2011 年 9 月 27 日更新。これを使用して、アーティストの曲数の取得を簡素化できることがわかりました。

int songs = [collection count];

私がしていたことではなく:

int songs = [[collection items] count];

ただし、実際には、これはパフォーマンスにほとんど影響を与えていません。

iPhone 3G を借りて、低速のデバイスでこの問題のパフォーマンスを試してみました。

私のコードは、この 3G で実行するのに 17.5 秒かかり、308 のアーティストにまたがる 637 曲しかありません。

曲数を取得する行をコメントアウトすると、同じデバイスがわずか0.7秒で終了します...

iOS デバイスでアーティストごとの曲数を取得するより高速な方法が必要です。

4

1 に答える 1

5

さらなる調査と試行錯誤の結果、 を使用してメディア ライブラリにクエリを実行し、artistsQuery各アーティストのコレクションをループする代わりに、NSNumbers の NSMutableDictionary を使用してアーティストごとの曲数を追跡するのが最も速い方法だと思います。

以下のコードを使用すると、デバイスの速度、アーティストの数、およびアーティストごとの曲の数に応じて、最初のアプローチよりも 1.5​​ 倍から 7 倍の速度の向上が見られます。(最大の増加は iPhone 3G で、最初は 945 曲で 21.5 秒かかりましたが、現在は 2.7 秒かかります!)

速度の改善が見つかった場合は、この回答を編集します。私はまだ Objective-C と iOS API に慣れていないので、私の回答を直接修正してください。(特に、NSMutableDictionary の NSNumbers を使用して以下に示す方法よりも高速に整数をハッシュ テーブルに格納する方法が見つからない可能性があります。)

NSMutableDictionary *artists = [[NSMutableDictionary alloc] init]; 
MPMediaQuery *query = [MPMediaQuery artistsQuery];
NSArray *items = [query items];
for (MPMediaItem *item in items)
{
     NSString *artistName = [item valueForProperty:MPMediaItemPropertyArtist];

    if (artistName != nil)
    {
        // retrieve current number of songs (could be nil)
        int numSongs = [(NSNumber*)[artists objectForKey:artistName] intValue];

        // increment the counter (could be set to 1 if numSongs was nil)
        ++numSongs;

        // store the new count
        [artists setObject:[NSNumber numberWithInt:numSongs] forKey:artistName];
    }
}
于 2011-09-28T05:51:04.133 に答える