2017-08-12 3 views
1

Es tut uns leid, im Voraus für so viel Code zu schreiben. Ich habe anscheinend ein Synchronisierungsproblem, das zum Absturz meiner App führt. Ich lege den ganzen Code in einen sync Thread, also bin ich nicht sicher, wie das möglich ist. Es stürzt an zwei verschiedenen Stellen ab, abhängig davon, wie oft die Funktion aufgerufen wird, aber ich vermute, dass die Ursache des Problems die gleiche ist. Bitte lassen Sie mich wissen, wenn Sie einen Rat haben.Synchronisationsproblem im synchronisierten Thread

-Code

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 
     } 
    } 

} 

Arten von Fehlermeldungen

fatal error: Index out of range

fatal error: UnsafeMutablePointer.deinitialize with negative count

+0

@rmaddy es funktioniert jetzt danke! –

Antwort

1

Eine klare Angelegenheit ist Ihr Missbrauch von DispatchQueue und sync. Sie erstellen jedes Mal eine neue Warteschlange, sodass der Zugriff auf die Eigenschaften nicht geschützt wird. Erstellen Sie eine einzelne Warteschlange als Instanzeigenschaft, und verwenden Sie sie jedes Mal. Dadurch wird sichergestellt, dass immer nur ein Thread auf den Code im sync-Block zugreifen kann.

Verwandte Themen