我有一个包含音乐库中所有歌曲列表的表格视图。 起初我拿起所有歌曲并将他们的信息保存到这样的数组中:
var songs = [Song]()
private func loadSongs(){
let itunesSongs = MPMediaQuery.songs().items
if itunesSongs == nil {
return;
}
for song in itunesSongs!{
let artist = song.albumArtist
let trackTitle = song.title
let image = song.artwork?.image(at: CGSize(width: 90, height: 90))
let url = song.assetURL?.absoluteString ?? ""
let song1 = Song(title: trackTitle ?? "", artist: artist ?? "", image: image, url: url)
songs.append(song1)
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "SongTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SongCell else {
fatalError("The dequeued cell is not an instance of SongCell.")
}
let song = playerManager.songs[indexPath.row]
cell.setAttributes(song: song)
cell.preservesSuperviewLayoutMargins = false
return cell
}
当我在拥有超过10000首歌曲的设备上测试时,启动App需要大约5-10秒。所以我修改了我填充表视图的方式,如下所示:
var itunesSongs: MPMediaQuery.songs().items
func getSong(index: Int) -> Song {
if(index >= songs.count){
let song = itunesSongs![index]
let ans = Song(title: song.title ?? "", artist: song.albumArtist ?? "", image: song.artwork?.image(at: CGSize(width: 90, height: 90)), url: song.assetURL?.absoluteString ?? "")
songs.append(ans)
}
return songs[index]
}
所以我会在getSong()
中使用tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
而不是songs
数组。
问题解决了,应用程序正常启动。但是,偶尔我会在Fatal error: Index out of range
行上获得return songs[index]
。
当我快速滚动并且每次都使用不同的索引时会发生这种情况。我试图一次取100首歌而不是1首,但这也没有解决它。
我正在考虑使用后台线程来填充songs
数组,但不确定这是否是正确的方法。
答案 0 :(得分:0)
问题是表视图没有按顺序调用getSong()
。例如,表格视图可以调用getSong(6)
,然后调用getSong(3)
。我将该功能更新为:
func getSong(index: Int) -> Song {
while (index >= songs.count){
let song = itunesSongs![songs.count]
let ans = Song(title: song.title ?? "", artist: song.albumArtist ?? "", image: song.artwork?.image(at: CGSize(width: 90, height: 90)), url: song.assetURL?.absoluteString ?? "")
songs.append(ans)
}
return songs[index]
}
答案 1 :(得分:0)
一种可能的解决方案
根本不要使用歌曲数组。也许将大量的物品(10000)附加到歌曲阵列中需要时间。代替
获取 viewdidLoad()中的歌曲
让itunesSongs = MPMediaQuery.songs()。items
在cellforRowAt中,从itunesSongs(标题,艺术家等)获取歌曲数据填充您的单元格并返回。像这样的事情
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "SongTableViewCell"
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SongCell else {
fatalError("The dequeued cell is not an instance of SongCell.")
}
let song = itunesSongs[indexPath.row]
cell.setAttributes(song: song)
cell.preservesSuperviewLayoutMargins = false
return cell
}