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,不是完全一样的东西,但至少内存这种方式不会导致崩溃.
我不熟悉 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)
轰轰!
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |