Ios 同步线程中的同步问题

Ios 同步线程中的同步问题,ios,swift,synchronization,Ios,Swift,Synchronization,很抱歉提前发布了这么多代码。我似乎有一个同步问题,导致我的应用程序崩溃。我把所有的代码放在一个sync线程中,所以我不确定这是怎么可能的。它在两个不同的地方崩溃,这取决于调用函数的频率,但我怀疑问题的根源是相同的。如果你有什么建议,请告诉我 代码 var curCollisionChecks = 0 func okToCheckForCollision() -> Bool { print(curCollisionChecks) if (curColli

很抱歉提前发布了这么多代码。我似乎有一个同步问题,导致我的应用程序崩溃。我把所有的代码放在一个
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
        }
    }
    
}
var curCollisionChecks=0
func okToCheckForCollision()->Bool{
打印(curCollisionChecks)
如果(curCollisionChecks<4){
让collisionQueue=DispatchQueue(标签:“collisionQueue”)
collisionQueue.sync{
curCollisionChecks+=1
}
返回真值
}
日志文本(文本:“警告:检查过多碰撞”)
日志文本(文本:“警告:某些可能被忽略”)
返回错误
}
func CheckColion(对象:UIView){
如果(!ViewThatRequireCheck.contains((objectToFO[object]?.name)!){
返回
}
让collisionQueue=DispatchQueue(标签:“collisionQueue”)
collisionQueue.sync{
如果(!okToCheckForCollision()){
返回
}
用于在objectToFO.keys中查看{
如果(!ViewThatRequireCheck.contains((objectToFO[view]?.name)!){
持续
}
设s0=[对象,视图]
设s1=[视图,对象]
if(view.frame.intersects(object.frame)){
if(视图==对象){
持续
}
var shouldContinue=false
对于碰撞状态中的combo{
如果(组合==s0){
shouldContinue=true
打破
}
如果(组合==s1){
shouldContinue=true
打破
}
}
如果(应该继续){
持续
}
collisionsStatus.append(s0)//有时在这里中断
冲突状态追加(s1)
设fo1=objectToFO[view]
设fo2=objectToFO[object]
if(viewToCollisionParents.keys.contains(视图)){
让script1=ScriptObjects[(fo1?.name)!]
对于ViewToCollevisionParents[view]中的curParent{
让deplexed=deplex(捕捉:curParent,对象:view)
if((将[0]解列为!字符串)=“我自己”){
if(fo2?.name==fo1?.name){
运行(发件人:视图,游标脚本:script1!,父级:curParent)
}
}
否则{
if(fo2?.name==(将[0]解译为!字符串)){
运行(发件人:视图,游标脚本:script1!,父级:curParent)
}
}
}
}
if(viewToCollisionParents.keys.contains(对象)){
让script2=ScriptObjects[(fo2?.name)!]
对于viewToCollisionParents[object]中的curParent{
让deplexed=deplex(捕捉:curParent,对象:object)
if((将[0]解列为!字符串)=“我自己”){
if(fo2?.name==fo1?.name){
运行(发送方:对象,curScript:script2!,父方:curParent)
}
}
否则{
if(fo1?.name==(将[0]解译为!字符串)){
运行(发送方:对象,curScript:script2!,父方:curParent)
}
}
}
}
}
否则{
var newCollisionsStatus=[[UIView]]()
//有时在这里休息
对于碰撞状态中的combo{
if(combo!=s0&&combo!=s1){
newCollisionStatus.append(组合)
}
}
碰撞状态=新碰撞状态
}
}
如果(curCollisionChecks>0){
curCollisionChecks-=1
}
}
}
错误消息的类型

致命错误:索引超出范围

致命错误:UnsaFemeutablePointer.deinitialize计数为负数


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

一个明显的问题是您误用了
DispatchQueue
sync
。每次都会创建一个新队列,因此它不会保护对属性的访问。创建一个队列作为实例属性,并每次使用它。这将确保一次只有一个线程可以访问
sync
块中的代码。

@rmaddy它现在可以工作了,谢谢@rmaddy现在可以用了谢谢!