【发布时间】:2018-10-07 16:47:37
【问题描述】:
我正在尝试从我的场景中删除一组代表路径的节点。它们是使用 SCNGeometrySource 和 SCNGeometryElement 创建的 SCNSphere 几何节点和自定义几何表示线的组合。
我不会在任何类型的数组中保留这些节点。相反,我在场景中 rootNode 的节点树的第一级搜索这些节点,按它们的名称,然后调用一个使它们淡出的动作序列,并且它们应该从根节点中删除自己。
代码如下:
func clearPath() {
//
let disappear = SCNAction.fadeOut(duration: 0.1)
let remove = SCNAction.removeFromParentNode()
let sequence = SCNAction.sequence([disappear, remove])
if let pathNodesToRemove = pathNodes() {
//
for node in pathNodesToRemove {
//
node.removeAllActions()
node.runAction(sequence)
}
}
if let lineNodesToRemove = lineNodes() {
for node in lineNodesToRemove {
//
node.removeAllActions()
node.runAction(sequence)
}
}
path.removeAll()
}
地点:
func pathNodes() -> [SCNNode]? {
//
...
let nodes = rootNode.childNodes.filter { (node) -> Bool in
//
guard let name = node.name else { return false }
if name.hasPrefix(configurationComponent.id) &&
name.range(of:"_PATH") != nil {
return true
} else {
return false
}
}
return nodes
}
lineNodes()函数基本相同。
我打开 Zombie Objects 以跟踪错误的来源,但我总是得到相同的错误:对 SceneKit`C3DNodeRemoveFromParentNode 的引用作为线程上调用的最后一件事,以及 EXC_BAD_ACCESS(代码=1,地址... )。
clearPath() 函数是整个应用程序中我调用“RemoveFromParentNode”的唯一位置。
节点上没有物理实体,也没有保留在其他任何地方。
关于如何解决这个问题的任何想法?
28/4/18 编辑:
这里是它发生的线程的崩溃报告。似乎 removeObjectFromChildNodesAtIndex 被调用了两次......
Thread 9 name: Dispatch queue: com.apple.scenekit.renderingQueue.Air_Relay.ARTCSCNView0x104126720
Thread 9 Crashed:
0 SceneKit 0x00000001957d668c C3DNodeRemoveFromParentNode + 40
1 SceneKit 0x0000000195826e28 -[SCNNode __removeObjectFromChildNodesAtIndex:] + 184
2 SceneKit 0x0000000195826e28 -[SCNNode __removeObjectFromChildNodesAtIndex:] + 184
3 SceneKit 0x0000000195827350 -[SCNNode removeFromParentNode] + 396
4 SceneKit 0x000000019593e9fc -[SCNActionRemove updateWithTarget:forTime:] + 92
5 SceneKit 0x0000000195907cb8 SCNCActionSequence::cpp_updateWithTargetForTime+ 2202808 (SCNNode*, double) + 316
6 SceneKit 0x00000001957bcfb0 SCNActionApply + 112
7 SceneKit 0x0000000195853d2c _applyActions + 236
8 CoreFoundation 0x00000001814dccbc __CFDictionaryApplyFunction_block_invoke + 24
9 CoreFoundation 0x00000001814c3f98 CFBasicHashApply + 132
10 CoreFoundation 0x00000001814cdb64 CFDictionaryApplyFunction + 288
11 SceneKit 0x0000000195853b5c C3DAnimationManagerApplyActions + 92
12 SceneKit 0x000000019583b054 -[SCNRenderer _update:] + 656
13 SceneKit 0x000000019583d018 -[SCNRenderer _drawSceneWithNewRenderer:] + 252
14 SceneKit 0x000000019583d69c -[SCNRenderer _drawScene:] + 84
15 SceneKit 0x000000019583daa0 -[SCNRenderer _drawAtTime:] + 728
16 SceneKit 0x00000001958e446c -[SCNView _drawAtTime:] + 512
编辑 30/04/18
我继续向应用程序添加其他功能,我需要使用 SCNAction.removeFromParentNode() 删除节点。我也隔离了这些,以独立于上述代码引起问题。
随着每个新节点的生成,这些在 SCNRendererDelegate 更新中被更频繁地调用。
我还尝试使用 SCNAction.run 块直接在节点上使用 removeFromParentNode() ,并且发生了同样的问题。
【问题讨论】:
-
如果我有一个保留周期,即使它们没有存储在数组中,我也会在 removeNodes 上崩溃。尝试在 Leaks 中检查您的参考计数。
-
pathNodes() 和 lineNodes() 是否有可能返回一个公共节点? path.removeAll() 有什么作用? (clearPath 方法的最后一行)