Fix bug around view.snp.layoutConstraints being dealloc’d

This commit is contained in:
Robert Payne 2016-09-07 20:23:54 +12:00
parent ca34ad4252
commit 2e4cebf41d
2 changed files with 30 additions and 11 deletions

View File

@ -46,7 +46,7 @@ public class Constraint {
self.updateConstantAndPriorityIfNeeded() self.updateConstantAndPriorityIfNeeded()
} }
} }
private let layoutConstraints: NSHashTable<LayoutConstraint> private var layoutConstraints: [LayoutConstraint]
// MARK: Initialization // MARK: Initialization
@ -66,7 +66,7 @@ public class Constraint {
self.multiplier = multiplier self.multiplier = multiplier
self.constant = constant self.constant = constant
self.priority = priority self.priority = priority
self.layoutConstraints = NSHashTable<LayoutConstraint>.weakObjects() self.layoutConstraints = []
// get attributes // get attributes
let layoutFromAttributes = self.from.attributes.layoutAttributes let layoutFromAttributes = self.from.attributes.layoutAttributes
@ -157,7 +157,7 @@ public class Constraint {
layoutConstraint.constraint = self layoutConstraint.constraint = self
// append // append
self.layoutConstraints.add(layoutConstraint) self.layoutConstraints.append(layoutConstraint)
} }
} }
@ -213,7 +213,7 @@ public class Constraint {
// MARK: Internal // MARK: Internal
internal func updateConstantAndPriorityIfNeeded() { internal func updateConstantAndPriorityIfNeeded() {
for layoutConstraint in self.layoutConstraints.allObjects { for layoutConstraint in self.layoutConstraints {
let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute
layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute) layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute)
layoutConstraint.priority = self.priority.constraintPriorityTargetValue layoutConstraint.priority = self.priority.constraintPriorityTargetValue
@ -222,7 +222,7 @@ public class Constraint {
internal func activateIfNeeded(updatingExisting: Bool = false) { internal func activateIfNeeded(updatingExisting: Bool = false) {
let view = self.from.view! let view = self.from.view!
let layoutConstraints = self.layoutConstraints.allObjects let layoutConstraints = self.layoutConstraints
let existingLayoutConstraints = view.snp.layoutConstraints let existingLayoutConstraints = view.snp.layoutConstraints
if updatingExisting && existingLayoutConstraints.count > 0 { if updatingExisting && existingLayoutConstraints.count > 0 {
@ -245,7 +245,7 @@ public class Constraint {
internal func deactivateIfNeeded() { internal func deactivateIfNeeded() {
let view = self.from.view! let view = self.from.view!
let layoutConstraints = self.layoutConstraints.allObjects let layoutConstraints = self.layoutConstraints
NSLayoutConstraint.deactivate(layoutConstraints) NSLayoutConstraint.deactivate(layoutConstraints)
view.snp.remove(layoutConstraints: layoutConstraints) view.snp.remove(layoutConstraints: layoutConstraints)
} }

View File

@ -101,17 +101,36 @@ public struct ConstraintViewDSL: ConstraintAttributesDSL {
} }
internal var layoutConstraints: [LayoutConstraint] { internal var layoutConstraints: [LayoutConstraint] {
return objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? [LayoutConstraint] ?? [] return self.layoutConstraintsHashTable.allObjects
} }
internal func add(layoutConstraints: [LayoutConstraint]) { internal func add(layoutConstraints: [LayoutConstraint]) {
let merged = self.layoutConstraints + layoutConstraints let hashTable = self.layoutConstraintsHashTable
objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) for layoutConstraint in layoutConstraints {
hashTable.add(layoutConstraint)
}
print(hashTable, self.layoutConstraintsHashTable)
} }
internal func remove(layoutConstraints: [LayoutConstraint]) { internal func remove(layoutConstraints: [LayoutConstraint]) {
let merged = self.layoutConstraints.filter { !layoutConstraints.contains($0) } let hashTable = self.layoutConstraintsHashTable
objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) for layoutConstraint in layoutConstraints {
hashTable.remove(layoutConstraint)
}
print(hashTable, self.layoutConstraintsHashTable)
}
private var layoutConstraintsHashTable: NSHashTable<LayoutConstraint> {
let layoutConstraints: NSHashTable<LayoutConstraint>
if let existing = objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? NSHashTable<LayoutConstraint> {
layoutConstraints = existing
} else {
layoutConstraints = NSHashTable<LayoutConstraint>.weakObjects()
objc_setAssociatedObject(self.view, &layoutConstraintsKey, layoutConstraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
return layoutConstraints
} }
} }