From c088e491c8b55efd4987fea33840281472ac3fe0 Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Tue, 7 Aug 2018 20:10:56 +0700 Subject: [PATCH 01/10] Unowned handler in Variable --- Source/bindings/Variable.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 } From 248450c458beb1d8e4068b80f5cc4287852b081e Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Tue, 7 Aug 2018 20:11:38 +0700 Subject: [PATCH 02/10] Cleaning nodesMap for group --- Source/model/scene/Group.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Source/model/scene/Group.swift b/Source/model/scene/Group.swift index e3c9e8ff..d189fbc6 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) { @@ -34,6 +39,12 @@ open class Group: Node { self.contents = contents self.contentsVar.node = self } + + deinit { + contentsVar.value.forEach { subNode in + nodesMap.remove(subNode) + } + } // Searching From d04206ab2299ed4ba82d4d2a97dcc5430986aec3 Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Tue, 7 Aug 2018 20:12:18 +0700 Subject: [PATCH 03/10] Formatting issues --- Source/model/scene/Group.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/model/scene/Group.swift b/Source/model/scene/Group.swift index d189fbc6..07b8c4e0 100644 --- a/Source/model/scene/Group.swift +++ b/Source/model/scene/Group.swift @@ -4,11 +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) { @@ -39,7 +39,7 @@ open class Group: Node { self.contents = contents self.contentsVar.node = self } - + deinit { contentsVar.value.forEach { subNode in nodesMap.remove(subNode) From d1bf4eb68830783ca4bf2d71e8a13140dd241684 Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 12:55:55 +0700 Subject: [PATCH 04/10] Removing group elements --- Source/views/NodesMap.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/views/NodesMap.swift b/Source/views/NodesMap.swift index f245a1ef..7851f583 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 From 84c964b829342e64fef6019aa132627d4a77865b Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 18:21:32 +0700 Subject: [PATCH 05/10] Optimise deletion of group node --- Source/model/scene/Group.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/model/scene/Group.swift b/Source/model/scene/Group.swift index 07b8c4e0..cf124e9f 100644 --- a/Source/model/scene/Group.swift +++ b/Source/model/scene/Group.swift @@ -41,9 +41,7 @@ open class Group: Node { } deinit { - contentsVar.value.forEach { subNode in - nodesMap.remove(subNode) - } + nodesMap.remove(self) } // Searching From 79a0cf4f74b3e3ec25172865f6f33297a95f293c Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 18:21:50 +0700 Subject: [PATCH 06/10] Fix leak in animation cache --- .../types/animation_generators/Cache/AnimationCache.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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() } From 2b8aae47b7873096793a6144d19a5473b049ac7d Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 18:21:59 +0700 Subject: [PATCH 07/10] Formatting fix --- Source/views/NodesMap.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/views/NodesMap.swift b/Source/views/NodesMap.swift index 7851f583..5207b6e3 100644 --- a/Source/views/NodesMap.swift +++ b/Source/views/NodesMap.swift @@ -29,7 +29,7 @@ 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) From 72bdcf57d4ebf71557f23105667a9f50d11723b2 Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 18:22:35 +0700 Subject: [PATCH 08/10] handlers links leak fixed --- Source/model/scene/Node.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) 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 } From 738e2a95af9320a34dd7deac4b534b95210a9ca8 Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 18:23:01 +0700 Subject: [PATCH 09/10] Added dispose on deinit --- Source/render/GroupRenderer.swift | 6 +++++- Source/render/ImageRenderer.swift | 4 ++++ Source/render/NodeRenderer.swift | 4 ++++ Source/render/ShapeRenderer.swift | 4 ++++ Source/render/TextRenderer.swift | 4 ++++ 5 files changed, 21 insertions(+), 1 deletion(-) 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..5890012e 100644 --- a/Source/render/NodeRenderer.swift +++ b/Source/render/NodeRenderer.swift @@ -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 } From ee7e29c00455ddb3877a357bf5f4aea12cab1d0a Mon Sep 17 00:00:00 2001 From: Anton Marunko Date: Wed, 8 Aug 2018 18:29:43 +0700 Subject: [PATCH 10/10] Fix for leak in renderer init --- Source/render/NodeRenderer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/render/NodeRenderer.swift b/Source/render/NodeRenderer.swift index 5890012e..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 }