title: Synchronization issue in synchronized thread
body: <p>Sorry ahead of time for posting so much code. I seem to have a synchronization issue causing my app to crash. I put all of the code in a <code>sync</code> thread so I'm not sure how this is possible. It crashes in two different places depending on how frequently the function is being called, but I suspect the source of the problem is the same. Please let me know if you have any advice.</p>
  <p><strong>Code</strong></p>
  <pre><code>var curCollisionChecks = 0
  
  func okToCheckForCollision() -&gt; Bool {
      
      print(curCollisionChecks)
      
      if (curCollisionChecks &lt; 4) {
          let collisionQueue = DispatchQueue(label: &quot;collisionQueue&quot;)
          collisionQueue.sync {
              curCollisionChecks += 1
          }
          return true
      }
      
      logText(text: &quot;WARNING: Checking too many collisions&quot;)
      logText(text: &quot;WARNING: Some may be ignored&quot;)
      
      return false
  }
  
  
  func checkColision(object: UIView) {
      
      if (!viewThatRequireChecking.contains((objectToFO[object]?.name)!)){
          return
      }
      
      let collisionQueue = DispatchQueue(label: &quot;collisionQueue&quot;)
      collisionQueue.sync {
          
          if (!okToCheckForCollision()) {
              return
          }
          
          for view in objectToFO.keys {
              
              if (!viewThatRequireChecking.contains((objectToFO[view]?.name)!)){
                  continue
              }
              
              let s0 = [object,view]
              let s1 = [view,object]
              
              if (view.frame.intersects(object.frame)) {
                  
                  if (view == object) {
                      continue
                  }
                  
                  var shouldContinue = false
                  
                  for combo in collisionsStatus {
                      if (combo == s0) {
                          shouldContinue = true
                          break
                      }
                      if (combo == s1) {
                          shouldContinue = true
                          break
                      }
                  }
                  
                  if (shouldContinue) {
                      continue
                  }
                  
                  collisionsStatus.append(s0) // SOMETIMES BREAKS HERE
                  collisionsStatus.append(s1)
                  
                  let fo1 = objectToFO[view]
                  let fo2 = objectToFO[object]
                  
                  if (viewToCollisionParents.keys.contains(view)) {
                      
                      let script1 = ScriptObjects[(fo1?.name)!]
                      for curParent in viewToCollisionParents[view]! {
                          
                          let deplexed = deplex(snap: curParent, object: view)
                          
                          if ((deplexed[0] as! String) == &quot;Myself&quot;) {
                              if (fo2?.name == fo1?.name) {
                                  run(sender: view, curScript: script1!, parent: curParent)
                              }
                          }
                          else {
                              if (fo2?.name == (deplexed[0] as! String)) {
                                  run(sender: view, curScript: script1!, parent: curParent)
                              }
                          }
                          
                      }
                  }
                  
                  if (viewToCollisionParents.keys.contains(object)) {
                      let script2 = ScriptObjects[(fo2?.name)!]
                      for curParent in viewToCollisionParents[object]! {
                          
                          let deplexed = deplex(snap: curParent, object: object)
                          
                          if ((deplexed[0] as! String) == &quot;Myself&quot;) {
                              if (fo2?.name == fo1?.name) {
                                  run(sender: object, curScript: script2!, parent: curParent)
                              }
                          }
                          else {
                              if (fo1?.name == (deplexed[0] as! String)) {
                                  run(sender: object, curScript: script2!, parent: curParent)
                              }
                          }
                          
                      }
                  }
                  
              }
              else {
                  var newCollisionsStatus = [[UIView]]()
                  // SOMETIMES BREAKS HERE
                  for combo in collisionsStatus {
                      if (combo != s0 &amp;&amp; combo != s1) {
                          newCollisionsStatus.append(combo)
                      }
                  }
                  collisionsStatus = newCollisionsStatus
              }
          }
          
          if (curCollisionChecks &gt; 0) {
              curCollisionChecks -= 1
          }
      }
      
  }
  </code></pre>
  <p><strong>Types of error messages</strong></p>
  <blockquote>
  <p>fatal error: Index out of range</p>
  <p>fatal error: UnsafeMutablePointer.deinitialize with negative count</p>
  </blockquote>