From 2e4cebf41d8bd0833487381590ed90c38b9a2491 Mon Sep 17 00:00:00 2001 From: Robert Payne Date: Wed, 7 Sep 2016 20:23:54 +1200 Subject: [PATCH] =?UTF-8?q?Fix=20bug=20around=20view.snp.layoutConstraints?= =?UTF-8?q?=20being=20dealloc=E2=80=99d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/Constraint.swift | 12 ++++++------ Source/ConstraintViewDSL.swift | 29 ++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Source/Constraint.swift b/Source/Constraint.swift index c6e5e01..2491c7b 100644 --- a/Source/Constraint.swift +++ b/Source/Constraint.swift @@ -46,7 +46,7 @@ public class Constraint { self.updateConstantAndPriorityIfNeeded() } } - private let layoutConstraints: NSHashTable + private var layoutConstraints: [LayoutConstraint] // MARK: Initialization @@ -66,7 +66,7 @@ public class Constraint { self.multiplier = multiplier self.constant = constant self.priority = priority - self.layoutConstraints = NSHashTable.weakObjects() + self.layoutConstraints = [] // get attributes let layoutFromAttributes = self.from.attributes.layoutAttributes @@ -157,7 +157,7 @@ public class Constraint { layoutConstraint.constraint = self // append - self.layoutConstraints.add(layoutConstraint) + self.layoutConstraints.append(layoutConstraint) } } @@ -213,7 +213,7 @@ public class Constraint { // MARK: Internal internal func updateConstantAndPriorityIfNeeded() { - for layoutConstraint in self.layoutConstraints.allObjects { + for layoutConstraint in self.layoutConstraints { let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute) layoutConstraint.priority = self.priority.constraintPriorityTargetValue @@ -222,7 +222,7 @@ public class Constraint { internal func activateIfNeeded(updatingExisting: Bool = false) { let view = self.from.view! - let layoutConstraints = self.layoutConstraints.allObjects + let layoutConstraints = self.layoutConstraints let existingLayoutConstraints = view.snp.layoutConstraints if updatingExisting && existingLayoutConstraints.count > 0 { @@ -245,7 +245,7 @@ public class Constraint { internal func deactivateIfNeeded() { let view = self.from.view! - let layoutConstraints = self.layoutConstraints.allObjects + let layoutConstraints = self.layoutConstraints NSLayoutConstraint.deactivate(layoutConstraints) view.snp.remove(layoutConstraints: layoutConstraints) } diff --git a/Source/ConstraintViewDSL.swift b/Source/ConstraintViewDSL.swift index a782ea9..21e1ac8 100644 --- a/Source/ConstraintViewDSL.swift +++ b/Source/ConstraintViewDSL.swift @@ -101,17 +101,36 @@ public struct ConstraintViewDSL: ConstraintAttributesDSL { } internal var layoutConstraints: [LayoutConstraint] { - return objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? [LayoutConstraint] ?? [] + return self.layoutConstraintsHashTable.allObjects } internal func add(layoutConstraints: [LayoutConstraint]) { - let merged = self.layoutConstraints + layoutConstraints - objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + let hashTable = self.layoutConstraintsHashTable + for layoutConstraint in layoutConstraints { + hashTable.add(layoutConstraint) + } + print(hashTable, self.layoutConstraintsHashTable) } internal func remove(layoutConstraints: [LayoutConstraint]) { - let merged = self.layoutConstraints.filter { !layoutConstraints.contains($0) } - objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + let hashTable = self.layoutConstraintsHashTable + for layoutConstraint in layoutConstraints { + hashTable.remove(layoutConstraint) + } + print(hashTable, self.layoutConstraintsHashTable) + } + + private var layoutConstraintsHashTable: NSHashTable { + let layoutConstraints: NSHashTable + + if let existing = objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? NSHashTable { + layoutConstraints = existing + } else { + layoutConstraints = NSHashTable.weakObjects() + objc_setAssociatedObject(self.view, &layoutConstraintsKey, layoutConstraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + return layoutConstraints + } }