2017-03-02 98 views
5

泄漏时,我有一个资产加载和缓存单定义为这样:SceneKit克隆一个节点

class AssetLoader { 
    fileprivate var rootNodes = Dictionary<String, SCNNode>() 

    static let sharedInstance = AssetLoader() 

    fileprivate init() { 
    } 

    func rootNode(_ named: String) -> SCNNode { 
     if self.rootNodes[named] != nil { 
      return self.rootNodes[named]!.clone() 
     } else { 
      let scene = SCNScene(named: "art.scnassets/\(named).scn") 
      self.rootNodes[named] = scene!.rootNode 
      return self.rootNodes[named]!.clone() 
     } 
    } 
} 

我使用它,使我的场景构建速度更快。我从分机创建资产如下:

extension CAAnimation { 
    class func animationWithScene(named: String) -> CAAnimation? { 
     unowned let rootNode = AssetLoader.sharedInstance.rootNode(named) 
     var animation: CAAnimation? 

     rootNode.enumerateChildNodes({ (child, stop) in 
      if child.animationKeys.count > 0 { 
       animation = child.animation(forKey: child.animationKeys.first!) 
       stop.initialize(to: true) 
      } 
     }) 
     return animation 
    } 
} 

extension SCNNode { 
    class func nodeWithScene(named: String) -> SCNNode? { 
     unowned let rootNode = AssetLoader.sharedInstance.rootNode(named) 
     let node = SCNNode() 

     for child in rootNode.childNodes { 
      node.addChildNode(child) 
     } 

     node.eulerAngles = SCNVector3(x: Float(-M_PI_2), y: 0, z: 0) 
     node.scale = SCNVector3Make(kMeshScale, kMeshScale, kMeshScale) 

     return node 
    } 
} 

仪器说我在每次调用clone()时都像疯了一样泄漏内存。我试图在不引起崩溃的情况下尽可能使用弱和无主的方法,但它不会改变任何内容。任何人都有线索?这是一个在SceneKit中的错误?

感谢

+0

我有同样的问题,你有没有发现什么是错了吗? –

回答

2

如果我理解正确的话你把你原来的节点在AssetLoader的rootNodes字典,并返回那些在根节点FUNC的克隆。

我的架构很相似,我的问题如下:当我从场景树中删除克隆节点时,内存不会被释放。这是你的问题吗?

我解决了这个问题,在从场景树中删除克隆节点时,通过在我的单例中添加“unload”func来使原始节点无效。这解决了我的记忆问题。

与您的代码看起来是这样的:

func unloadRootNode(_ named: String) { 
    rootNodes.removeValue(forKey: named) 
} 
+0

我不再为此工作(从此改变了工作),但如果它解决了Florent的问题,我会标记为已接受。看起来很有希望。 –