diff --git a/Source/animation/types/animation_generators/Cache/AnimationCache.swift b/Source/animation/types/animation_generators/Cache/AnimationCache.swift index 0934ca20..2fff8860 100644 --- a/Source/animation/types/animation_generators/Cache/AnimationCache.swift +++ b/Source/animation/types/animation_generators/Cache/AnimationCache.swift @@ -19,7 +19,7 @@ class AnimationCache { } } - let sceneLayer: CALayer + weak var sceneLayer: CALayer? var layerCache = [Node: CachedLayer]() required init(sceneLayer: CALayer) { @@ -74,10 +74,10 @@ class AnimationCache { layer.contentsScale = calculateAnimationScale(animation: animation) layer.setNeedsDisplay() - sceneLayer.addSublayer(layer) + sceneLayer?.addSublayer(layer) layerCache[node] = CachedLayer(layer: layer, animation: animation) - sceneLayer.setNeedsDisplay() + sceneLayer?.setNeedsDisplay() return layer } @@ -138,7 +138,7 @@ class AnimationCache { let layer = cachedLayer.layer layerCache.removeValue(forKey: node) - sceneLayer.setNeedsDisplay() + sceneLayer?.setNeedsDisplay() layer.removeFromSuperlayer() } diff --git a/Source/bindings/Variable.swift b/Source/bindings/Variable.swift index c2a97975..ea34c1c2 100644 --- a/Source/bindings/Variable.swift +++ b/Source/bindings/Variable.swift @@ -36,7 +36,7 @@ open class Variable { @discardableResult open func onChange(_ f: @escaping ((T) -> Void)) -> Disposable { let handler = ChangeHandler(f) handlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.handlers.index(of: handler) else { return } diff --git a/Source/model/scene/Group.swift b/Source/model/scene/Group.swift index e3c9e8ff..cf124e9f 100644 --- a/Source/model/scene/Group.swift +++ b/Source/model/scene/Group.swift @@ -4,6 +4,11 @@ open class Group: Node { open var contents: [Node] { get { return contentsVar.value } set(val) { + + contentsVar.value.forEach { subNode in + nodesMap.remove(subNode) + } + contentsVar.value = val if let view = nodesMap.getView(self) { @@ -35,6 +40,10 @@ open class Group: Node { self.contentsVar.node = self } + deinit { + nodesMap.remove(self) + } + // Searching override public func nodeBy(tag: String) -> Node? { diff --git a/Source/model/scene/Node.swift b/Source/model/scene/Node.swift index e1e5686a..7d06174a 100644 --- a/Source/model/scene/Node.swift +++ b/Source/model/scene/Node.swift @@ -85,7 +85,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) touchPressedHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.touchPressedHandlers.index(of: handler) else { return } @@ -98,7 +98,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) touchMovedHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.touchMovedHandlers.index(of: handler) else { return } @@ -111,7 +111,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) touchReleasedHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.touchReleasedHandlers.index(of: handler) else { return } @@ -128,7 +128,7 @@ open class Node: Drawable { tapHandlers[tapCount] = [handler] } - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.tapHandlers[tapCount]?.index(of: handler) else { return } @@ -141,7 +141,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) longTapHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.longTapHandlers.index(of: handler) else { return } @@ -154,7 +154,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) panHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.panHandlers.index(of: handler) else { return } @@ -167,7 +167,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) rotateHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.rotateHandlers.index(of: handler) else { return } @@ -180,7 +180,7 @@ open class Node: Drawable { let handler = ChangeHandler(f) pinchHandlers.append(handler) - return Disposable { [weak self] in + return Disposable { [weak self, unowned handler] in guard let index = self?.pinchHandlers.index(of: handler) else { return } diff --git a/Source/render/GroupRenderer.swift b/Source/render/GroupRenderer.swift index 556ed075..b5088fc8 100644 --- a/Source/render/GroupRenderer.swift +++ b/Source/render/GroupRenderer.swift @@ -18,6 +18,10 @@ class GroupRenderer: NodeRenderer { updateRenderers() } + deinit { + dispose() + } + override func doAddObservers() { super.doAddObservers() @@ -53,7 +57,7 @@ class GroupRenderer: NodeRenderer { override func dispose() { super.dispose() renderers.forEach { renderer in renderer.dispose() } - renderers = [] + renderers.removeAll() } private func updateRenderers() { diff --git a/Source/render/ImageRenderer.swift b/Source/render/ImageRenderer.swift index f1308f11..12210b55 100644 --- a/Source/render/ImageRenderer.swift +++ b/Source/render/ImageRenderer.swift @@ -18,6 +18,10 @@ class ImageRenderer: NodeRenderer { super.init(node: image, view: view, animationCache: animationCache) } + deinit { + dispose() + } + override func node() -> Node? { return image } diff --git a/Source/render/NodeRenderer.swift b/Source/render/NodeRenderer.swift index 687edc00..b17287ab 100644 --- a/Source/render/NodeRenderer.swift +++ b/Source/render/NodeRenderer.swift @@ -28,7 +28,7 @@ class NodeRenderer { self.view = view self.animationCache = animationCache - onNodeChange = { + onNodeChange = { [unowned node, weak view] in guard let isAnimating = animationCache?.isAnimating(node) else { return } @@ -43,6 +43,10 @@ class NodeRenderer { addObservers() } + deinit { + disposables.dispose() + } + func doAddObservers() { guard let node = node() else { return diff --git a/Source/render/ShapeRenderer.swift b/Source/render/ShapeRenderer.swift index a71b55fa..97df9d3d 100644 --- a/Source/render/ShapeRenderer.swift +++ b/Source/render/ShapeRenderer.swift @@ -15,6 +15,10 @@ class ShapeRenderer: NodeRenderer { super.init(node: shape, view: view, animationCache: animationCache) } + deinit { + dispose() + } + override func node() -> Node? { return shape } diff --git a/Source/render/TextRenderer.swift b/Source/render/TextRenderer.swift index 83a8fb4e..913a9b04 100644 --- a/Source/render/TextRenderer.swift +++ b/Source/render/TextRenderer.swift @@ -14,6 +14,10 @@ class TextRenderer: NodeRenderer { super.init(node: text, view: view, animationCache: animationCache) } + deinit { + dispose() + } + override func node() -> Node? { return text } diff --git a/Source/views/NodesMap.swift b/Source/views/NodesMap.swift index f245a1ef..5207b6e3 100644 --- a/Source/views/NodesMap.swift +++ b/Source/views/NodesMap.swift @@ -29,6 +29,12 @@ class NodesMap { func remove(_ node: Node) { map.removeObject(forKey: node) parentsMap.removeValue(forKey: node) + + if let group = node as? Group { + group.contents.forEach { child in + self.remove(child) + } + } } // MARK: - Parents