【发布时间】:2016-06-22 15:20:01
【问题描述】:
您好,对于 swift 和一般编程来说还是新手。
我有这个以指定音高播放一段音频的功能。它被一个 NStimer 调用,所以每秒播放一次。 (函数包含在 SoundPlayer 类中,然后设置 NStimer 并在 viewController 中使用)
func playPitchedAudio(audioFile: AVAudioFile, pitch: Float){
audioEngine.stop()
audioEngine.reset()
let audioPlayerNode = AVAudioPlayerNode()
let changePitchEffect = AVAudioUnitTimePitch()
changePitchEffect.pitch = pitch
audioEngine.attachNode(audioPlayerNode)
audioEngine.attachNode(changePitchEffect)
audioEngine.connect(audioPlayerNode, to: changePitchEffect, format: nil)
audioEngine.connect(changePitchEffect, to: audioEngine.outputNode, format: nil)
audioPlayerNode.scheduleFile(audioFile, atTime: nil, completionHandler: nil)
do {
try audioEngine.start()
} catch {
print("error")
}
audioPlayerNode.play()
}
它运行良好且工作正常,但每次调用时都会向内存添加几 MB 并且永远不会重新获得空间。对内存泄漏进行了一些研究,但找不到任何对我的具体情况有帮助的东西,所以希望有人能指出我正确的方向。
我认为这与创建一个新节点有关,并且每次调用 TimePitch 时都会将它们移动到包含该函数的类中,但出现“libc++abi.dylib:以 NSException 类型的未捕获异常终止”错误当声音第二次尝试播放时。
非常感谢任何帮助,谢谢!
额外的东西。
// defined in class to be used by function
var pitchedAudioPlayer = AVAudioPlayerNode()
var audioEngine = AVAudioEngine()
//Timer Start
self.timer.invalidate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(tempo, target: self, selector: #selector(ViewController.timeTriggerPointer), userInfo: nil, repeats: true)
//Timer calls... (along with some other unrelated stuff)
func timeTriggerPointer() {
soundPlayer.playPitchedAudio(pitchFilePath, pitch: -1000.0)
}
解决方案 -
import AVFoundation
class SoundPlayer {
var pitchedAudioPlayer = AVAudioPlayerNode()
var audioEngine = AVAudioEngine()
let audioPlayerNode = AVAudioPlayerNode()
let changePitchEffect = AVAudioUnitTimePitch()
init() {
audioEngine.attachNode(audioPlayerNode)
audioEngine.attachNode(changePitchEffect)
audioEngine.connect(audioPlayerNode, to: changePitchEffect, format: nil)
audioEngine.connect(changePitchEffect, to: audioEngine.outputNode, format: nil)
}
func playPitchedAudio(audioFile: AVAudioFile, pitch: Float){
audioPlayerNode.stop()
changePitchEffect.pitch = pitch
audioPlayerNode.scheduleFile(audioFile, atTime: nil, completionHandler: nil)
do {
try audioEngine.start()
} catch {
print("error")
}
audioPlayerNode.play()
}
}
【问题讨论】:
-
有什么问题?是泄漏还是崩溃?
-
对不起,泄漏是问题所在。崩溃是我修复泄漏的失败尝试。
-
如何插入?将是问题。我不确定我是否有泄漏,但是当我运行计时器时,内存使用量不断增加,直到大约 120mb,然后崩溃。当我使用 AVAudioPlayer 时,该应用程序运行良好(但这不允许改变音高),所以肯定是这个功能导致了它。我不知道如何追踪泄漏,我尝试过使用仪器,但在这个阶段它有点超出我的能力,并且似乎指向我没有编写的代码,所以并没有真正帮助我。不知道如何直接在 Xcode 中进行。感谢您的帮助!
-
您阅读我的回答了吗(如下)?这不是泄漏。只是您创建对象,直到内存不足。停止这样做,一切都会好起来的。