0

我正在编写一个使用 cocoalibspotify 的 iPhone 应用程序。在我的一个视图中,我希望能够在表格视图中显示播放列表的所有 SPTrack。每个单元格应显示艺术家、专辑和曲目名称。我已经实现了一种异步检索播放列表内容的方法,但我还没有找到在后台线程上将 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 方法。在此方法的回调中,我将轨道添加到数组中。这就是问题所在:在主线程中添加这些对象会导致一些延迟。所以我的问题是:

  1. 这是检索 SPPlaylist 中所有 SPTrack 对象的正确方法吗?如果不是,那么在后台线程上执行此操作以使我的 UI 不被阻塞的正确方法是什么?

感谢您提供任何帮助!

4

1 回答 1

0

通过 URL 创建一个新的轨道是非常低效的——它SPPlaylistItem包含轨道本身。

将您通过 URL 获取曲目的部分替换为类似这样的内容,您应该没问题:

for (SPPlaylistItem *item in playlist.items) {
    if (item.itemClass == [SPTrack class])
        [mutableArray addObject:item.item];
}

此外,值得注意的是,一次从播放列表中获取所有曲目是一个相当糟糕的主意 - 播放列表变得非常大,当你一次只有 20 个左右的屏幕上时保持 10,000 首曲目会让你跑很快就内存不足。

于 2013-04-24T11:18:50.957 回答