2011-09-26 2 views
2

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

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


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

int songs = [collection count]; 

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

int songs = [[collection items] count]; 

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

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

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

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

Там должен быть более быстрым способом получить количество песен на художник на устройстве IOS.

ответ

3

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

Используя приведенный ниже код, я вижу улучшение скорости от 1.5x до 7x по сравнению с моим первоначальным подходом, в зависимости от скорости устройства, количества исполнителей и количества песен для каждого исполнителя. (Самое большое увеличение - это 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]; 
    } 
}