소스 검색

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

Robert Payne 9 년 전
부모
커밋
2e4cebf41d
2개의 변경된 파일30개의 추가작업 그리고 11개의 파일을 삭제
  1. 6 6
      Source/Constraint.swift
  2. 24 5
      Source/ConstraintViewDSL.swift

+ 6 - 6
Source/Constraint.swift

@@ -46,7 +46,7 @@ public class Constraint {
           self.updateConstantAndPriorityIfNeeded()
         }
     }
-    private let layoutConstraints: NSHashTable<LayoutConstraint>
+    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<LayoutConstraint>.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)
     }

+ 24 - 5
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<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
+        
     }
     
 }