An even better way to handle this is to use an NSOperationQueue and NSOperation. A nice tutorial that is relevant to this question can be found here.
How can I improve the performance for obtaining indexed sections for UITableView
-
04-04-2022 - |
题
I am creating indexed sections for a table view to display song titles from the iPod Library. To accomplish this, I am utilizing sectionForObject:collationStringSelector: in a loop through all mediaItems from a song query. The following code executes in viewDidLoad in order to obtain the number of sections and number of rows per section of the table:
// Go through the collection of songs and collate them into sections A-Z
for (MPMediaItemCollection *arrayItem in itemsFromSongQuery) {
MPMediaItem *representativeItem = [arrayItem representativeItem]; // grab the next object from the collection
NSString *songName = [representativeItem valueForProperty: MPMediaItemPropertyTitle];
MPMediaItemArtwork *artWork = [representativeItem valueForProperty: MPMediaItemPropertyArtwork];
channelButtonTitles *aChannelButtonTitle = [[channelButtonTitles alloc] init]; // create an object to hold both the title and section number
aChannelButtonTitle.channelTitle = songName; // save the song name string in this object
aChannelButtonTitle.channelSubTitle = [representativeItem valueForProperty: MPMediaItemPropertyArtist]; // save the artists string in this object
aChannelButtonTitle.artwork = [artWork imageWithSize:CGSizeMake(30, 30)]; // save the artwork UIImage object
aChannelButtonTitle.persistentID = [representativeItem valueForProperty:MPMediaEntityPropertyPersistentID]; // save this unique number in case the user wants to play this
// Then determine which section number it belongs to.
// The collator will use the channelTitle property of the aChannelButtonTitle object to make this determination
NSInteger sect = [theCollation sectionForObject:aChannelButtonTitle collationStringSelector:@selector(channelTitle)];
aChannelButtonTitle.sectionNumber = sect; // Save the section number that this title string should be assigned to.
[tempTitles addObject:aChannelButtonTitle]; // Copy the channelButtonTitles object that contains the title and section number in the temp array
[aChannelButtonTitle release]; // Release the channelButtonTitles object
}
Unfortunately, for 2000 songs, this takes nearly 15 seconds. The time to allocate the channelButtonTitle object and the execution time of the sectionForObject:collationStringSelector: are both negligible.
It seems that much of this time is spent in the lines that obtain valueForProperty, although the line:
MPMediaItem *representativeItem = [arrayItem representativeItem];
takes 5 seconds.
How can I improve the performance of creating the indexed sections (or at least improve the time that the user is waiting for something to happen)?
解决方案 2
其他提示
For lack of any other suggestions, I found that I can cut the time in half by moving the following 2 lines into tableView:cellForRowAtIndexPath:
MPMediaItemArtwork *artWork = [representativeItem valueForProperty: MPMediaItemPropertyArtwork];
aChannelButtonTitle.artwork = [artWork imageWithSize:CGSizeMake(30, 30)]; // save the artwork UIImage object
aChannelButtonTitle.channelSubTitle = [representativeItem valueForProperty: MPMediaItemPropertyArtist]; // save the artists string in this object
Thus, viewDidLoad still captures the song title (for the purpose of preparing the indexed table) and the persistentID (to enable tableView:cellForRowAtIndexPath: to easily grab the artwork and subtitle). It still could use some improvement, but its better.