2017-03-02 15 views
5

Tôi có một tải tài sản và bộ nhớ đệm singleton định nghĩa như vậy:SceneKit rò rỉ khi nhân rộng một nút

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

Tôi đang sử dụng nó để làm cảnh của tôi xây dựng nhanh hơn. Tôi đang tạo nội dung từ các tiện ích mở rộng như vậy:

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

Cụ đang nói rằng tôi đang rò rỉ bộ nhớ như điên trên mỗi cuộc gọi để sao chép(). Tôi đã cố gắng sử dụng yếu và unowned bất cứ nơi nào tôi có thể mà không gây ra tai nạn và nó không thay đổi bất cứ điều gì. Bất cứ ai cũng có một đầu mối? Đó có phải là một lỗi trong SceneKit không?

Cảm ơn

+0

Tôi đang gặp vấn đề tương tự, đã bao giờ bạn tìm hiểu những gì đã xảy ra? –

Trả lời

2

Nếu tôi hiểu đúng bạn giữ nút gốc của bạn trong từ điển rootNodes của AssetLoader của bạn và trả về một bản sao của những người trong func rootNode.

Kiến trúc của tôi tương tự và vấn đề của tôi là như sau: khi tôi xóa nút nhân bản khỏi cây cảnh, bộ nhớ sẽ không được giải phóng. Đó có phải là vấn đề của bạn không?

Tôi đã khắc phục sự cố bằng cách thêm func "unload" vào singleton của tôi để vô hiệu hóa các nút gốc khi xóa các nút nhân bản khỏi cây cảnh. Điều đó đã khắc phục được vấn đề về bộ nhớ của tôi.

Với mã của bạn sẽ giống như thế:

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

Tôi không còn làm việc này (thay đổi công việc kể từ đó) nhưng nếu nó giải quyết được vấn đề của Florent, tôi sẽ đánh dấu là chấp nhận. Có vẻ đầy hứa hẹn. –