【问题标题】:Index of NSMutableArray not start with 0NSMutableArray 的索引不以 0 开头
【发布时间】:2017-05-30 09:11:08
【问题描述】:

我正在尝试将值(文档目录中的 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)") 

所有文件都是:2

所有文件 :("Cake By The Ocean.mp3","LoveSong.mp3")

看来数数没问题!有2 文件,但问题是数组的索引以0 开头,所以在这种情况下player.MP3DirectoryFiles.count 应该是:1,这意味着:0,1。 [在表格视图中]

我不得不说,在表格视图中选择单元格和播放歌曲时一切正常,但是在音乐完成后会发生这种情况。 我需要一些帮助来解决这个问题,如果有帮助,这里有更多代码:

编辑 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)
    }

另一个视图控制器:

  func musicIsFinished(notification:Notification)  {

        _trackRow = appDefaults.loadTrackNumber()


        if _trackRow > player.MP3DirectoryFiles.count {

            _trackRow = 0


        } else {

            _trackRow! += 1

        }

                player.playMusic(at: _trackRow!)
                prepareToPlay()


    }

【问题讨论】:

  • "player.MP3DirectoryFiles.count 应该是:1,这意味着:0,1",实际上计数应该是 2,因为数组包含 2 个对象。
  • @JamesP 那么索引的数量呢?
  • 你可能想要if currentTrack == array.count-1 { //is last track }
  • @JamesP 发生同样的崩溃!而且不是标准方式!
  • 什么不是标准的?显示崩溃的代码。

标签: ios arrays swift xcode nsmutablearray


【解决方案1】:

好的,所以你的数组中有两首歌曲。

当您开始播放第一首歌曲时,您说...在位置 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()
}

希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 2017-05-22
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    相关资源
    最近更新 更多