XCode仪器中SCNNode上SCNAudioPlayer的持久性

Man*_*ese 8 instruments ios swift scnnode

我创建了一个子类SCNNode.它由很少的子节点组成.我已经宣布了一种方法,即.soundCasual()这会SCNAudioPlayer为此类的实例添加一个.当调用此方法时,一切都按预期工作并播放音频.无论何时轻敲该节点(手势),都会在该节点上调用此方法.

码:

class MyNode: SCNNode {
    let wrapperNode = SCNNode()
    let audioSource5 = SCNAudioSource(fileNamed: "audiofile.mp3")

    override init() {
        super.init()

        if let virtualScene = SCNScene(named: "MyNode.scn", inDirectory: "Assets.scnassets/Shapes/MyNode") {
            for child in virtualScene.rootNode.childNodes {
                wrapperNode.addChildNode(child)
            }
        }
    }

   func soundCasual() {
        DispatchQueue.global(qos: .userInteractive).async { [weak self] in
            if let audioSource = self?.audioSource5 {
                let audioPlayer = SCNAudioPlayer(source: audioSource)
                self?.wrapperNode.removeAllAudioPlayers()
                self?.wrapperNode.addAudioPlayer(audioPlayer)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

仪器内的问题(分配)

当我分析我的整个代码库(这是其他几件事)时,我看到每当我点击该节点时,SCNAudioPlayer的分配计数在Instruments内进行分析时增加1.但所有的增长都是持久的.根据定义SCNAudioPlayer,我假设玩家在播放后被移除,这就是为什么增量应该在瞬态分配中,但它不是这样工作的.这就是为什么我removeAllAudioPlayers()在向节点添加SCNAudioPlayer之前尝试过,正如您在代码中看到的那样soundCasual().但问题仍然存在.

直到这个快照拍摄,我已经在该节点上轻敲了17次,并且它还显示了17个针对SCNAudioPlayer的持久分配.

注意:SCNAudioSource应该是10,因为我在应用程序中使用了10个音频源

在此输入图像描述

并且我的应用程序中的所有其他SCNNode都会发生这种情况.请帮助,因为我无法理解我到底错过了什么.

编辑

按照建议,我改变了我init()

let path = Bundle.main.path(forResource: "Keemo", ofType: "scn", inDirectory: "Assets.scnassets/Shapes/Keemo")
if let path = path , let keemo = SCNReferenceNode(url: URL(fileURLWithPath: path)) {
    keemo.load()
}
func soundPlay() {
    DispatchQueue.global(qos: .userInteractive).async { [weak self] in
        if let audioSource = self?.audioSourcePlay {
            audioSource.volume = 0.1
            let audioPlayer = SCNAudioPlayer(source: audioSource)
            self?.removeAllAudioPlayers()
            self?.addAudioPlayer(audioPlayer)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

尽管如此,仪器中的分配显示audioPlayers持久.虽然在检查时node.audioPlayers它显示在某一点上,只有一个audioPlayer节点附加.

编辑

即使在我使用在XCode中默认创建的Scenekit应用程序中附加的样板代码库的情况下,这个问题也会出现.因此,这个问题已经成为Apple的一个错误.https://bugreport.apple.com/web/?problemID=43482539

替代方法

我使用AVAudioPlayer而不是SCNAudioPlayer,不是完全一样的东西,但至少内存这种方式不会导致崩溃.

Ste*_*ani 1

我不熟悉 SceneKit,但根据我对 UIKit 和 SpriteKit 的经验,我怀疑您对wrapperNode和的使用virtualScene正在扰乱垃圾收集器。

我会尝试删除wrapperNode所有内容并将其添加到self(因为self是 a SCNNode)。

您的场景中正在使用哪个节点?self或者wrapperNode?并且您的示例代码wrapperNode未添加到其中self,因此它实际上可能是也可能不是场景的一部分。

另外,您可能应该使用SCNReferenceNode而不是您正在使用的虚拟场景。

!!!此代码尚未经过测试!

class MyNode: SCNReferenceNode {
    let audioSource5 = SCNAudioSource(fileNamed: "audiofile.mp3")

    func soundCasual() {
        DispatchQueue.global(qos: .userInteractive).async { [weak self] in
            if let audioSource = self?.audioSource5 {
                let audioPlayer = SCNAudioPlayer(source: audioSource)
                self?.removeAllAudioPlayers()
                self?.addAudioPlayer(audioPlayer)
            }
        }
    }
}


// If you programmatically create this node, you'll have to call .load() on it
let referenceNode = SCNReferenceNode(URL: referenceURL)
referenceNode.load()
Run Code Online (Sandbox Code Playgroud)

轰轰!