无法操作位于不同 ViewController 上的 AVAudioPlayer
Cannot manipulate AVAudioPlayer located on different ViewController
我有两个 ViewController。一个是"ViewController",第二个是"SecondViewController".
在ViewController,我有var player = AVAudioPlayer()
。我已经在那里成功加载并播放了BGM,然后我将SecondViewController推入了视野。
在第二个ViewController 上,我使用此代码停止 ViewController 上的音频播放器:
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController") as? ViewController
viewController?.player.pause()
但是我得到错误 Thread 1: EXC_BAD_ACCESS (code=1, address=0x38)
据我浏览了解,发生这种情况是因为我在播放器尚未初始化时尝试访问播放器。
但这怎么可能呢?不是已经初始化了吗?直到发生此错误时,音乐仍在播放。出了什么问题以及如何解决它以便我可以从与当前活动的不同 ViewController 操作音频播放器(但它已经在后台活动)?谢谢
instantiateViewControllerWithIdentifier 创建视图控制器的新实例。
改为在 YourViewController 类型的 secondViewController 上放置一个 属性,并在 YourViewController 的 prepareForSegue 中设置它。
您正在实例化一个新的视图控制器;不使用呈现 SecondViewController 的相同视图控制器,因此创建的 AudioPlayer 与之前的 AudioPlayer 不同。您应该以某种方式引用呈现视图控制器。
一种方法是通过所谓的委托模式,
class ViewController: UIViewController {
...
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SecondViewController" {
if let secondViewController = segue.destinationViewController as? SecondViewController {
secondViewController.delegate = self
}
}
}
// MARK: SecondViewControllerDelegate
func stopPlayer() {
player.stopPlayer()
}
}
protocol SecondViewControllerDelegate {
func stopPlayer()
}
class SecondViewController: UIViewController {
...
var delegate: SecondViewControllerDelegate?
func stopPlayer() {
delegate?.stopPlayer()
}
}
或者,您也可以将 AVPlayer 从第一个视图控制器传递给 SecondViewController,并使用它从 SecondViewController 本身停止,
class ViewController: UIViewController {
...
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SecondViewController" {
if let secondViewController = segue.destinationViewController as? SecondViewController {
secondViewController.player = self.player
}
}
}
}
class SecondViewController: UIViewController {
...
var player: AVPlayer!
func stop() {
player.stop()
}
}
问题是 instantiateViewControllerWithIdentifier
创建了一个 new ViewController。它不是 return 你一直在使用的那个。无论如何,尝试访问以前的视图控制器上的某些东西对我来说似乎不是一个好的设计。
一种选择是将 AVAudioPlayer
传递给 prepareForSegue
方法中的第二个 VC。您可以声明一个 AVAudioPlayer
属性 并将其设置在那里。
我有两个 ViewController。一个是"ViewController",第二个是"SecondViewController".
在ViewController,我有var player = AVAudioPlayer()
。我已经在那里成功加载并播放了BGM,然后我将SecondViewController推入了视野。
在第二个ViewController 上,我使用此代码停止 ViewController 上的音频播放器:
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("ViewController") as? ViewController
viewController?.player.pause()
但是我得到错误 Thread 1: EXC_BAD_ACCESS (code=1, address=0x38)
据我浏览了解,发生这种情况是因为我在播放器尚未初始化时尝试访问播放器。
但这怎么可能呢?不是已经初始化了吗?直到发生此错误时,音乐仍在播放。出了什么问题以及如何解决它以便我可以从与当前活动的不同 ViewController 操作音频播放器(但它已经在后台活动)?谢谢
instantiateViewControllerWithIdentifier 创建视图控制器的新实例。
改为在 YourViewController 类型的 secondViewController 上放置一个 属性,并在 YourViewController 的 prepareForSegue 中设置它。
您正在实例化一个新的视图控制器;不使用呈现 SecondViewController 的相同视图控制器,因此创建的 AudioPlayer 与之前的 AudioPlayer 不同。您应该以某种方式引用呈现视图控制器。
一种方法是通过所谓的委托模式,
class ViewController: UIViewController {
...
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SecondViewController" {
if let secondViewController = segue.destinationViewController as? SecondViewController {
secondViewController.delegate = self
}
}
}
// MARK: SecondViewControllerDelegate
func stopPlayer() {
player.stopPlayer()
}
}
protocol SecondViewControllerDelegate {
func stopPlayer()
}
class SecondViewController: UIViewController {
...
var delegate: SecondViewControllerDelegate?
func stopPlayer() {
delegate?.stopPlayer()
}
}
或者,您也可以将 AVPlayer 从第一个视图控制器传递给 SecondViewController,并使用它从 SecondViewController 本身停止,
class ViewController: UIViewController {
...
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SecondViewController" {
if let secondViewController = segue.destinationViewController as? SecondViewController {
secondViewController.player = self.player
}
}
}
}
class SecondViewController: UIViewController {
...
var player: AVPlayer!
func stop() {
player.stop()
}
}
问题是 instantiateViewControllerWithIdentifier
创建了一个 new ViewController。它不是 return 你一直在使用的那个。无论如何,尝试访问以前的视图控制器上的某些东西对我来说似乎不是一个好的设计。
一种选择是将 AVAudioPlayer
传递给 prepareForSegue
方法中的第二个 VC。您可以声明一个 AVAudioPlayer
属性 并将其设置在那里。