mirror of https://github.com/SnapKit/SnapKit
Fix Memory Leaks
This commit is contained in:
parent
ddf15594fd
commit
eb107818ac
|
@ -27,7 +27,8 @@
|
||||||
import AppKit
|
import AppKit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public class Constraint {
|
@objc(SnapKitConstraint)
|
||||||
|
public final class Constraint : NSObject {
|
||||||
|
|
||||||
internal let sourceLocation: (String, UInt)
|
internal let sourceLocation: (String, UInt)
|
||||||
internal let label: String?
|
internal let label: String?
|
||||||
|
@ -67,6 +68,7 @@ public class Constraint {
|
||||||
self.constant = constant
|
self.constant = constant
|
||||||
self.priority = priority
|
self.priority = priority
|
||||||
self.layoutConstraints = []
|
self.layoutConstraints = []
|
||||||
|
super.init()
|
||||||
|
|
||||||
// get attributes
|
// get attributes
|
||||||
let layoutFromAttributes = self.from.attributes.layoutAttributes
|
let layoutFromAttributes = self.from.attributes.layoutAttributes
|
||||||
|
@ -260,7 +262,7 @@ public class Constraint {
|
||||||
}
|
}
|
||||||
|
|
||||||
for layoutConstraint in layoutConstraints {
|
for layoutConstraint in layoutConstraints {
|
||||||
let existingLayoutConstraint = existingLayoutConstraints.first { $0.canUpdate(constraint: layoutConstraint) }
|
let existingLayoutConstraint = existingLayoutConstraints.first { $0 == layoutConstraint }
|
||||||
guard let updateLayoutConstraint = existingLayoutConstraint else {
|
guard let updateLayoutConstraint = existingLayoutConstraint else {
|
||||||
fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)")
|
fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)")
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class ConstraintDescription {
|
||||||
let sourceLocation = self.sourceLocation else {
|
let sourceLocation = self.sourceLocation else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let from = ConstraintItem(target: self.item as AnyObject, attributes: self.attributes)
|
let from = ConstraintItem(target: self.item, attributes: self.attributes)
|
||||||
|
|
||||||
return Constraint(
|
return Constraint(
|
||||||
from: from,
|
from: from,
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public class ConstraintItem : Equatable {
|
public final class ConstraintItem {
|
||||||
|
|
||||||
internal weak var target: AnyObject?
|
internal weak var target: AnyObject?
|
||||||
internal let attributes: ConstraintAttributes
|
internal let attributes: ConstraintAttributes
|
||||||
|
|
|
@ -160,20 +160,42 @@ public class ConstraintMaker {
|
||||||
internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
|
internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
|
||||||
let maker = ConstraintMaker(item: item)
|
let maker = ConstraintMaker(item: item)
|
||||||
closure(maker)
|
closure(maker)
|
||||||
let constraints = maker.descriptions
|
var constraints: [Constraint] = []
|
||||||
.map { $0.constraint }
|
for description in maker.descriptions {
|
||||||
.filter { $0 != nil }
|
guard let constraint = description.constraint else {
|
||||||
.map { $0! }
|
continue
|
||||||
|
}
|
||||||
|
constraints.append(constraint)
|
||||||
|
}
|
||||||
return constraints
|
return constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
|
internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
|
||||||
let maker = ConstraintMaker(item: item)
|
let maker = ConstraintMaker(item: item)
|
||||||
closure(maker)
|
closure(maker)
|
||||||
let constraints = maker.descriptions
|
var constraints: [Constraint] = []
|
||||||
.map { $0.constraint }
|
for description in maker.descriptions {
|
||||||
.filter { $0 != nil }
|
|
||||||
.map { $0! }
|
guard let relation = description.relation,
|
||||||
|
let related = description.related,
|
||||||
|
let sourceLocation = description.sourceLocation else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let from = ConstraintItem(target: description.item, attributes: description.attributes)
|
||||||
|
|
||||||
|
let constraint = Constraint(
|
||||||
|
from: from,
|
||||||
|
to: related,
|
||||||
|
relation: relation,
|
||||||
|
sourceLocation: sourceLocation,
|
||||||
|
label: description.label,
|
||||||
|
multiplier: description.multiplier,
|
||||||
|
constant: description.constant,
|
||||||
|
priority: description.priority
|
||||||
|
)
|
||||||
|
|
||||||
|
constraints.append(constraint)
|
||||||
|
}
|
||||||
for constraint in constraints {
|
for constraint in constraints {
|
||||||
constraint.activateIfNeeded(updatingExisting: false)
|
constraint.activateIfNeeded(updatingExisting: false)
|
||||||
}
|
}
|
||||||
|
@ -192,10 +214,13 @@ public class ConstraintMaker {
|
||||||
|
|
||||||
let maker = ConstraintMaker(item: item)
|
let maker = ConstraintMaker(item: item)
|
||||||
closure(maker)
|
closure(maker)
|
||||||
let constraints = maker.descriptions
|
var constraints: [Constraint] = []
|
||||||
.map { $0.constraint }
|
for description in maker.descriptions {
|
||||||
.filter { $0 != nil }
|
guard let constraint = description.constraint else {
|
||||||
.map { $0! }
|
continue
|
||||||
|
}
|
||||||
|
constraints.append(constraint)
|
||||||
|
}
|
||||||
for constraint in constraints {
|
for constraint in constraints {
|
||||||
constraint.activateIfNeeded(updatingExisting: true)
|
constraint.activateIfNeeded(updatingExisting: true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,33 +59,33 @@ extension LayoutConstraintItem {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
internal var constraints: [Constraint] {
|
internal var constraints: [Constraint] {
|
||||||
return self.constraintsHashTable.allObjects
|
return self.constraintsSet.allObjects as! [Constraint]
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func add(constraints: [Constraint]) {
|
internal func add(constraints: [Constraint]) {
|
||||||
let hashTable = self.constraintsHashTable
|
let constraintsSet = NSMutableSet()
|
||||||
for constraint in constraints {
|
for constraint in constraints {
|
||||||
hashTable.add(constraint)
|
constraintsSet.add(constraint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal func remove(constraints: [Constraint]) {
|
internal func remove(constraints: [Constraint]) {
|
||||||
let hashTable = self.constraintsHashTable
|
let constraintsSet = NSMutableSet()
|
||||||
for constraint in constraints {
|
for constraint in constraints {
|
||||||
hashTable.remove(constraint)
|
constraintsSet.remove(constraint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var constraintsHashTable: NSHashTable<Constraint> {
|
private var constraintsSet: NSMutableSet {
|
||||||
let constraints: NSHashTable<Constraint>
|
let constraintsSet: NSMutableSet
|
||||||
|
|
||||||
if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSHashTable<Constraint> {
|
if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSMutableSet {
|
||||||
constraints = existing
|
constraintsSet = existing
|
||||||
} else {
|
} else {
|
||||||
constraints = NSHashTable<Constraint>()
|
constraintsSet = NSMutableSet()
|
||||||
objc_setAssociatedObject(self, &constraintsKey, constraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
objc_setAssociatedObject(self, &constraintsKey, constraintsSet, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||||
}
|
}
|
||||||
return constraints
|
return constraintsSet
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue