Ios 不良访问、多线程、GCD、swift

Ios 不良访问、多线程、GCD、swift,ios,swift,grand-central-dispatch,Ios,Swift,Grand Central Dispatch,我正在尝试将objective-c中的一些示例代码翻译成swift 除了多线程部分外,我让它都能正常工作,这对于这个模拟非常关键 由于某种原因,当我开始使用多线程时,它会出现访问错误。从数组中获取或设置内容时的特殊情况 该类在静态类中实例化 var screenWidthi:Int = 0 var screenHeighti:Int = 0 var poolWidthi:Int = 0 var poolHeighti:Int = 0 var rippleSource:[GLfloat] = [

我正在尝试将objective-c中的一些示例代码翻译成swift

除了多线程部分外,我让它都能正常工作,这对于这个模拟非常关键

由于某种原因,当我开始使用多线程时,它会出现访问错误。从数组中获取或设置内容时的特殊情况

该类在静态类中实例化

var screenWidthi:Int = 0
var screenHeighti:Int = 0
var poolWidthi:Int = 0
var poolHeighti:Int = 0

var rippleSource:[GLfloat] = []
var rippleDest:[GLfloat] = []

func update()
{
        let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

        dispatch_apply(Int(poolHeighti), queue, {(y: size_t) -> Void in
        //for y in 0..<poolHeighti
        //{
            let pw = self.poolWidthi
            for x in 1..<(pw - 1)
            {
                let ai:Int = (y    ) * (pw + 2) + x + 1
                let bi:Int = (y + 2) * (pw + 2) + x + 1
                let ci:Int = (y + 1) * (pw + 2) + x
                let di:Int = (y + 1) * (pw + 2) + x + 2
                let me:Int = (y + 1) * (pw + 2) + x + 1

                let a = self.rippleSource[ai]
                let b = self.rippleSource[bi]
                let c = self.rippleSource[ci]
                let d = self.rippleSource[di]

                var result = (a + b + c + d) / 2.0 - self.rippleDest[me]
                result -= result / 32.0

                self.rippleDest[me] = result
            }
        }
        )
}
var屏幕宽度i:Int=0
变量屏幕高度i:Int=0
变量PoolWidthSi:Int=0
var poolHeighti:Int=0
var rippleSource:[GLfloat]=[]
变量RippleTest:[GLfloat]=[]
func update()
{
let queue=dispatch\u get\u global\u queue(dispatch\u queue\u PRIORITY\u默认值,0)
调度应用(Int(poolHeighti),队列,{(y:size\u t)->Void in

//对于0..中的y,Apple代码使用C样式的数组,如果使用得当,这些数组是“线程安全的”——就像Apple代码一样

Swift和Objective-C数组不是线程安全的,这就是问题的原因。您需要对数组实施某种形式的访问控制

一种简单的方法是将GCD顺序队列与每个数组相关联,然后向数组中写入dispatch async到该队列,然后读取dispatch sync。这很简单,但会减少并发性,以便更好地读取。对于Swift代码

如果你需要理解这些问题,迈克·阿什(Mike Ash)是个不错的选择。对于Swift代码,请阅读所有答案和评论


HTH

这对我来说是个糟糕的措词,苹果写了代码,但它是在目标c中。我修正了措词。提供回溯可能会有用…@jcaron我添加了一张我认为是回溯的一部分的图片。有用吗?谢谢,这很有意义!它无法解释我放在代码底部的异常情况但这可能只是一个异常,我需要以比0.5 fps快得多的速度运行它说NSArray是线程安全的在swift中也是一样的吗?如果我在类中有一个作为静态方法的线程安全数组,它还会是线程安全的吗?一般来说,不可变的类型/值应该是线程安全的,例如
NSArray
let v=array value
。线程安全不应该受到静态方法使用的影响ably应该研究线程安全与否的原因,了解这一点可以回答类似的问题。至于您的异常情况,它不是。您通过添加打印更改了单个并发线程的执行时间,您可能引入了隐藏锁定/同步(内部打印).Thread safety是关于单独的非同步线程中操作之间的随机交互,你已经改变了这些线程正在做的事情…是时候做这项研究了!刚刚下载了从2011年到现在关于并发编程的所有wwdic演讲:)非常感谢!
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply(poolHeight, queue, ^(size_t y) {
        for (int x=0; x<poolWidth; x++)
        {
            float a = rippleSource[(y)*(poolWidth+2) + x+1];
            float b = rippleSource[(y+2)*(poolWidth+2) + x+1];
            float c = rippleSource[(y+1)*(poolWidth+2) + x];
            float d = rippleSource[(y+1)*(poolWidth+2) + x+2];

            float result = (a + b + c + d)/2.f - rippleDest[(y+1)*(poolWidth+2) + x+1];

            result -= result/32.f;

            rippleDest[(y+1)*(poolWidth+2) + x+1] = result;
        }            
    });