2017-08-12 181 views
1

抱歉提前发布这么多代码。我似乎有一个同步问题,导致我的应用程序崩溃。我把所有的代码放在sync线程中,所以我不确定这是如何实现的。它根据函数被调用的频率在两个不同的地方崩溃,但我怀疑问题的根源是一样的。如果您有任何建议,请告诉我。同步线程中的同步问题

代码

var curCollisionChecks = 0 

func okToCheckForCollision() -> Bool { 

    print(curCollisionChecks) 

    if (curCollisionChecks < 4) { 
     let collisionQueue = DispatchQueue(label: "collisionQueue") 
     collisionQueue.sync { 
      curCollisionChecks += 1 
     } 
     return true 
    } 

    logText(text: "WARNING: Checking too many collisions") 
    logText(text: "WARNING: Some may be ignored") 

    return false 
} 


func checkColision(object: UIView) { 

    if (!viewThatRequireChecking.contains((objectToFO[object]?.name)!)){ 
     return 
    } 

    let collisionQueue = DispatchQueue(label: "collisionQueue") 
    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) == "Myself") { 
          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) == "Myself") { 
          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 && combo != s1) { 
         newCollisionsStatus.append(combo) 
        } 
       } 
       collisionsStatus = newCollisionsStatus 
      } 
     } 

     if (curCollisionChecks > 0) { 
      curCollisionChecks -= 1 
     } 
    } 

} 

错误信息的类型

fatal error: Index out of range

fatal error: UnsafeMutablePointer.deinitialize with negative count

+0

@rmaddy现在的作品谢谢你! –

回答

1

一个明显的问题是,你的DispatchQueuesync滥用。您每次创建一个新队列,因此它无法保护对这些属性的访问。创建一个单个队列作为实例属性并每次使用它。这将确保一次只有一个线程可以访问sync块中的代码。