Какой самый быстрый способ в iOS получить количество песен для конкретного исполнителя?

Я пытаюсь получить всех исполнителей на локальном устройстве 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 секунды.

Поэтому мне интересно, есть ли более быстрый способ получить количество песен для артистов, чем то, что я делаю выше?


Обновление от 27 сентября 2011 г. Я вижу, что могу упростить поиск количества песен для исполнителя, используя это:

int songs = [collection count];

Вместо того, что я делал:

int songs = [[collection items] count];

Однако на практике это мало повлияло на производительность.

Я одолжил iPhone 3G, чтобы попробовать решить эту проблему на более медленном устройстве.

Мой код запускается на этом 3G всего за 17,5 секунд, всего 637 песен, распределенных по 308 исполнителям.

Если я закомментирую строку, которая извлекает количество песен, то же устройство завершит работу всего за 0,7 секунды...

Должен быть более быстрый способ получить количество песен на исполнителя на устройстве iOS.


person Mason G. Zhwiti    schedule 26.09.2011    source источник


Ответы (1)


После дальнейших исследований и проб и ошибок я считаю, что самый быстрый способ — запросить медиатеку с помощью artistsQuery, и вместо циклического просмотра коллекции каждого исполнителя вы отслеживаете количество песен на исполнителя, используя NSMutableDictionary NSNumbers.

Используя приведенный ниже код, я вижу улучшение скорости от 1,5 до 7 раз по сравнению с моим первоначальным подходом, в зависимости от скорости устройства, количества исполнителей и количества песен на исполнителя. (Самый большой прирост был у iPhone 3G, который сначала занимал 21,5 секунды для 945 песен, а теперь это занимает 2,7 секунды!)

Я отредактирую этот ответ, если обнаружу какие-либо улучшения скорости. Пожалуйста, не стесняйтесь исправлять что-либо прямо в моем ответе, так как я все еще новичок в Objective-C и API iOS. (В частности, мне может не хватать более быстрого способа хранения целых чисел в хеш-таблице, чем то, что я получил ниже с NSNumbers в NSMutableDictionary?)

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];
    }
}
person Community    schedule 28.09.2011