我正在编写一个使用cocoalibspotify的iPhone应用程序。在我的一个视图中,我希望能够在表视图中显示播放列表的所有SPTracks。每个单元格应该显示艺术家、专辑和曲目的名称。我已经实现了一种异步检索播放列表内容的方法,但我还没有找到正确的方法来执行SPPlaylistItems在后台线程上转换为SPTrack对象。因此,每次我检索播放列表曲目时,我的UI都会延迟。当然,延迟是非常小的,但它仍然令人讨厌。这是我的方法,检索播放列表的内容。
-(void)getPlaylistContentAsynchronouslyOfPlaylist:(NSString *)playlistName callback:(void (^)(NSArray *playlistTracks))block{
NSLog(@"Getting content ansynchronously...");
NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
SPPlaylist *playlist = [self getPlaylistWithName:playlistName];
__block BOOL addedAllTracks = mutableArray.count == playlist.items.count;
for (SPPlaylistItem *item in playlist.items){
NSLog(@"----Checking Track with url %@", item.itemURL.absoluteString);
NSURL *trackURL = [item.item spotifyURL];
[[SPSession sharedSession]trackForURL:trackURL callback:^(SPTrack * spotifyTrack){
if(spotifyTrack){
//NSLog(@"---->>>Adding Track with url %@", item.itemURL.absoluteString);
[mutableArray addObject:spotifyTrack];
}
if (mutableArray.count == playlist.items.count){
//NSLog(@"!!!!!!!Added all songs!");
addedAllTracks = YES;
}
}];
}
dispatch_async(self.backgroundQueue, ^{
NSLog(@"Retrieving playlist content asynchronously...");
while (!addedAllTracks){
NSLog(@"<><><><>BG Queue is waiting....");
[NSThread sleepForTimeInterval:0.25];
}
if (block){
NSLog(@"Done retrieving playlist content asynchronously");
NSLog(@"*******Passing %d tracks to the caller", mutableArray.count);
dispatch_async(dispatch_get_main_queue(), ^() { block(mutableArray); });
}
});
}
为了从SPPlaylistItem中检索SPTrack,我使用SPSession的trackForURL方法。在这个方法的回调中,我将轨道添加到一个数组中。这就是问题所在:在主线程中添加这些对象会导致一些延迟。所以我的问题是:
- 这是检索所有SPTrack对象在SPPlaylist中的正确方式吗?如果不是,什么是正确的方法来做这个在后台线程,使我的UI不阻塞?
任何帮助都是感激的,谢谢!
通过URL创建一个新的轨道是非常低效的- SPPlaylistItem
包含轨道本身。
用这样的东西替换你按URL获取跟踪的部分,你应该没问题:
for (SPPlaylistItem *item in playlist.items) {
if (item.itemClass == [SPTrack class])
[mutableArray addObject:item.item];
}
此外,值得注意的是,一次从播放列表中获取所有的曲目是一个相当糟糕的主意——播放列表会变得非常大,当屏幕上一次只有20个左右的曲目时,保留10,000首曲目会让你很快耗尽内存。