NSMutableArray 的索引不是以 0 开头
Index of NSMutableArray not start with 0
我正在尝试将值(文档目录中的 MP3 文件)添加到 NSMutableArray
。我正在创建一个音乐播放器,所以当一首歌曲播放完毕后,我的方法应该通过 AVAudioPlayer Delegate
播放下一首歌曲。我写了一个 if
语句并检查当前曲目是否大于 array.count
它应该播放索引为 0
.
的第一首歌曲
问题是应用程序因以下错误而崩溃:fatal error: Array index out of range
然后我打印我的数组,这里发生了一些奇怪的事情:
print("all files are :\(player.MP3DirectoryFiles.count)")
print("all files :\(player.MP3DirectoryFiles.description)")
all files are :2
all files :(" Cake By The Ocean.mp3","LoveSong.mp3" )
看来数数还行!有 2
个文件,但问题是数组的索引以 0
开头,所以在这种情况下 player.MP3DirectoryFiles.count
应该是:1
,这意味着:0,1
。 [在 TABLE 视图中]
我不得不说在 table 查看 select 单元格和播放歌曲时一切正常,但在音乐结束后就会发生这种情况。
我需要一些帮助来解决这个问题,如果有帮助,这里有更多代码:
已编辑 2:
func playMusic(at:Int) {
let musicFile = MP3DirectoryFiles[at] as! NSString
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let musicURL = documentsDirectory.appendingPathComponent(musicFile.lastPathComponent)
getDataFromTrack(file: musicURL)
do {
player = try AVAudioPlayer(contentsOf: musicURL)
player.prepareToPlay()
player.delegate = self
appDefaults.setTrack(duration: Float(player.duration))
} catch let error as NSError {
print(error.description)
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
NotificationCenter.default.post(name: NSNotification.Name("musicIsFinished"), object: nil)
}
另一个ViewController :
func musicIsFinished(notification:Notification) {
_trackRow = appDefaults.loadTrackNumber()
if _trackRow > player.MP3DirectoryFiles.count {
_trackRow = 0
} else {
_trackRow! += 1
}
player.playMusic(at: _trackRow!)
prepareToPlay()
}
好的,你的数组中有两首歌。
当您开始播放第一首歌曲时,您说...在位置 0 播放歌曲(因为 NSMutableArrays
是从零开始的...正如您所知:))
一旦歌曲结束,您的 musicIsFinished
方法就会被调用。
在这里您可以查看接下来要播放的内容。
目前 _trackRow
是 0,因为那是你刚刚播放的歌曲,player.MP3DirectoryFiles.count
是 2。
您的代码如下所示:
if _trackRow > player.MP3DirectoryFiles.count {
_trackRow = 0
} else {
_trackRow! += 1
}
所以你最终进入 else
。 _trackRow
递增,现在为 1。
接下来你问 playSong(at: 1)
就可以了(我希望 :))
好的...下一首歌曲已完成,我们回到 musicIsFinished
。 _trackRow
是 1 而 player.MP3DirectoryFiles.count
仍然是 2
那么,你再检查一下:
if _trackRow > player.MP3DirectoryFiles.count
不是这样 _trackRow
递增到 2 然后你要求你的数组在索引 2
处给你歌曲
但是……索引二没有歌曲对吧?您的数组是从零开始的,因此您在索引 0 和索引 1 处有一首歌曲,但在索引 2 处没有……所以……您的应用程序变得混乱和崩溃。
你需要把你的if _trackRow > player.MP3DirectoryFiles.count
转过来问:
if _trackRow < player.MP3DirectoryFiles.count - 1
意思是:
第一次你进入musicIsFinished
的时候你最终进入了else
部分,因为
_trackRow
是 0
player.MP3DirectoryFiles.count - 1
是 1
且0小于1
自
以来,秒 时间在 if
部分结束
_trackRow
是 1
player.MP3DirectoryFiles.count - 1
是 1
且1不小于1
说来话长,但请尝试将您的 musicIsFinished
更改为:
func musicIsFinished(notification:Notification) {
_trackRow = appDefaults.loadTrackNumber()
if _trackRow < player.MP3DirectoryFiles.count - 1 {
_trackRow += 1
} else {
_trackRow = 0
}
player.playMusic(at: _trackRow!)
prepareToPlay()
}
希望对你有所帮助。
我正在尝试将值(文档目录中的 MP3 文件)添加到 NSMutableArray
。我正在创建一个音乐播放器,所以当一首歌曲播放完毕后,我的方法应该通过 AVAudioPlayer Delegate
播放下一首歌曲。我写了一个 if
语句并检查当前曲目是否大于 array.count
它应该播放索引为 0
.
问题是应用程序因以下错误而崩溃:fatal error: Array index out of range
然后我打印我的数组,这里发生了一些奇怪的事情:
print("all files are :\(player.MP3DirectoryFiles.count)")
print("all files :\(player.MP3DirectoryFiles.description)")
all files are :2
all files :(" Cake By The Ocean.mp3","LoveSong.mp3" )
看来数数还行!有 2
个文件,但问题是数组的索引以 0
开头,所以在这种情况下 player.MP3DirectoryFiles.count
应该是:1
,这意味着:0,1
。 [在 TABLE 视图中]
我不得不说在 table 查看 select 单元格和播放歌曲时一切正常,但在音乐结束后就会发生这种情况。 我需要一些帮助来解决这个问题,如果有帮助,这里有更多代码:
已编辑 2:
func playMusic(at:Int) {
let musicFile = MP3DirectoryFiles[at] as! NSString
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let musicURL = documentsDirectory.appendingPathComponent(musicFile.lastPathComponent)
getDataFromTrack(file: musicURL)
do {
player = try AVAudioPlayer(contentsOf: musicURL)
player.prepareToPlay()
player.delegate = self
appDefaults.setTrack(duration: Float(player.duration))
} catch let error as NSError {
print(error.description)
}
}
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
NotificationCenter.default.post(name: NSNotification.Name("musicIsFinished"), object: nil)
}
另一个ViewController :
func musicIsFinished(notification:Notification) {
_trackRow = appDefaults.loadTrackNumber()
if _trackRow > player.MP3DirectoryFiles.count {
_trackRow = 0
} else {
_trackRow! += 1
}
player.playMusic(at: _trackRow!)
prepareToPlay()
}
好的,你的数组中有两首歌。
当您开始播放第一首歌曲时,您说...在位置 0 播放歌曲(因为 NSMutableArrays
是从零开始的...正如您所知:))
一旦歌曲结束,您的 musicIsFinished
方法就会被调用。
在这里您可以查看接下来要播放的内容。
目前 _trackRow
是 0,因为那是你刚刚播放的歌曲,player.MP3DirectoryFiles.count
是 2。
您的代码如下所示:
if _trackRow > player.MP3DirectoryFiles.count {
_trackRow = 0
} else {
_trackRow! += 1
}
所以你最终进入 else
。 _trackRow
递增,现在为 1。
接下来你问 playSong(at: 1)
就可以了(我希望 :))
好的...下一首歌曲已完成,我们回到 musicIsFinished
。 _trackRow
是 1 而 player.MP3DirectoryFiles.count
仍然是 2
那么,你再检查一下:
if _trackRow > player.MP3DirectoryFiles.count
不是这样 _trackRow
递增到 2 然后你要求你的数组在索引 2
但是……索引二没有歌曲对吧?您的数组是从零开始的,因此您在索引 0 和索引 1 处有一首歌曲,但在索引 2 处没有……所以……您的应用程序变得混乱和崩溃。
你需要把你的if _trackRow > player.MP3DirectoryFiles.count
转过来问:
if _trackRow < player.MP3DirectoryFiles.count - 1
意思是:
第一次你进入musicIsFinished
的时候你最终进入了else
部分,因为
_trackRow
是 0player.MP3DirectoryFiles.count - 1
是 1
且0小于1
自
以来,秒 时间在if
部分结束
_trackRow
是 1player.MP3DirectoryFiles.count - 1
是 1
且1不小于1
说来话长,但请尝试将您的 musicIsFinished
更改为:
func musicIsFinished(notification:Notification) {
_trackRow = appDefaults.loadTrackNumber()
if _trackRow < player.MP3DirectoryFiles.count - 1 {
_trackRow += 1
} else {
_trackRow = 0
}
player.playMusic(at: _trackRow!)
prepareToPlay()
}
希望对你有所帮助。