在大多数情况下,您触发异步系统调用并将其传递给资源,系统会保留对该资源的强引用,以便它仍然可用。
AVAudioPlayer
似乎是一个例外。
代码
func playSound() {
guard let soundFileURL = Bundle.main.url(forResource:"Shut your festering Gob", withExtension: "mp3") else {
return
}
let player = try? AVAudioPlayer(contentsOf: soundFileURL)
player?.play()
}
不起作用,因为当函数返回并且音频播放器被取消分配时,局部变量player
超出范围。
相反,只要它运行,调度Timer
就会保留该计时器的目标。这似乎是基础课程的常态。
似乎AVFoundation
应该在播放期间对AVAudioPlayer
拥有一个拥有的引用。
是否有人知道AVFoundation
在播放期间保留音频播放器的具体原因?
答案 0 :(得分:3)
鞋子在另一只脚上。当局部上下文结束时(执行到达周围花括号的末尾),局部变量超出范围并且不存在是正常的。其他行为是不寻常的。因此,您应该问为什么以及如何保留计时器!正如福尔摩斯所说的那样,这是一个奇怪的事件。
答案是当你安排计时器时,你明确地要求保留它(通过当前的runloop)。这只是计时器的特殊架构。但是,通常会保留对计时器的引用,以防您需要invalidate
。