2017-03-02 64 views
5

mam obciążenie zasobów i buforowania singleton zdefiniowany jako takie:SceneKit przecieka podczas klonowania węzła

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() 
     } 
    } 
} 

Używam go, aby moja scena budowy szybciej. Tworzę zasoby z rozszerzeń jako takich:

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 
    } 
} 

Instrumenty mówią, że przecieka pamięć jak szalona przy każdym wywołaniu klonowania(). Próbowałem używać słabych i niezarejestrowanych, gdzie tylko mogłem, bez powodowania awarii i niczego nie zmieniając. Ktoś ma jakąś wskazówkę? Czy to błąd w SceneKit?

Dzięki

+0

Mam ten sam problem, czy kiedykolwiek dowiedzieć się, co się stało? –

Odpowiedz

2

Jeśli rozumiem poprawnie zachować swoje oryginalne węzły w rootNodes Słownik swojej AssetLoader i powrócić klon tych w func Rootnode.

Moja architektura jest podobna, a mój problem był następujący: gdybym usunął sklonowany węzeł z drzewa scen, pamięć nie zostałaby zwolniona. Czy to twój problem?

Rozwiązałem problem, dodając funkcję "unload" w moim singletonie, aby unieważnić oryginalne węzły podczas usuwania sklonowanych węzłów z drzewa sceny. To naprawiło moje problemy z pamięcią.

z kodem, który będzie wyglądać mniej więcej tak:

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

Nie pracuję już nad tym (zmieniłem pracę od tego czasu), ale jeśli rozwiązał problem Florenta, zaznaczę to jako zaakceptowany. Wygląda obiecująco. –