ios - Xcode Instrument 中 SCNNodes 上 SCNAudioPlayer 的持久化

标签 ios swift instruments 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)
            }
        }
    }
}

工具(分配)中的问题

当我分析我的整个代码库(这是其他几件事)时,我发现每当我点击该节点时,SCNAudioPlayer 的分配计数都会增加 1,同时在 Instruments 中进行分析。但所有的增加都是持久的。根据 SCNAudioPlayer 的定义,我假设这个播放器在播放后被删除,这就是增量应该在 transient 分配中的原因,但它不是这样工作的。这就是为什么我在将 SCNAudioPlayer 添加到节点之前尝试使用 removeAllAudioPlayers(),如您在 soundCasual() 的代码中所见。但问题依然存在。

在拍摄此快照之前,我已经点击了该节点大约 17 次,它还显示 17 次针对 SCNAudioPlayer 的持久分配。

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

enter image description here

我的应用程序中的所有其他 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)
        }
    }
}

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

编辑

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

解决方法

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

最佳答案

我不熟悉 SceneKit,但根据我使用 UIKit 和 SpriteKit 的经验,我怀疑您对 wrapperNodevirtualScene 的使用会干扰垃圾收集器。

我会尝试删除 wrapperNode 并将所有内容添加到 self(因为 self 是一个 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()

嗯!

关于ios - Xcode Instrument 中 SCNNodes 上 SCNAudioPlayer 的持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51431512/

相关文章:

swift - 使用 rxSwift 绑定(bind)数据时内存泄漏

iphone - 在 Instruments 中分析 iPhone 应用程序时缺少符号名称

ios - 配置文件已过期

ios - TestFlight 提供反馈按钮

ios - 滚动 UICollectionView 时如何自定义在顶部屏幕上粘滞的标题 View ?

ios - Firebase 观察大型数据库缓慢

swift - @State 静态属性正在重新启动,恕不另行通知

ios - "count"在仪器内存分配的调用树中到底意味着什么?

ios - Xcode 8 图像补全

ios - 如何判断核心数据管理对象何时具有用于设置 toMany 关系的动态方法?