糟糕的进攻,多线程,GCD,快速

时间:2016-09-04 07:19:21

标签: 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] = []
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
            }
        }
        )
}

重要的是要注意,还有一个循环应该在这个之后的另一个线程上运行,它会访问相同的数组。可以说,如果没有在另一个线程中使用第二个线程,它仍然会很糟糕,因此我觉得显示它是不可靠的。

如果你能告诉我发生了什么事情导致这次事故发生在随机时间而不是第一次。

如果你想参考这里是客观c中的样子

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

如何确保能够从不同的线程访问变量?静态成员怎么样?

我只是在应用程序崩溃之前没有如何打印调用堆栈,但是之后,我知道进入调用堆栈的唯一方法是查看线程。如果我有不同的方式,请告诉我。 enter image description here

注意:我发现了一些奇怪的事情。我在每个循环中都放了一个print语句,这样我就可以看到它处理的x和y坐标,看看崩溃是否一致。很明显,这使得fps低于1 fps,但我确实注意到它还没有崩溃。到目前为止,该程序运行完美,没有任何不良影响,只需不到1 fps。

1 个答案:

答案 0 :(得分:3)

Apple代码使用的是C风格的数组,如果使用得当,它们是“线程安全的” - 正如Apple代码那样。

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

一种简单的方法是将GCD顺序队列与每个数组相关联,然后将数组分派异步写入此队列,并读取分派同步。这很简单,但会降低并发性,使其更好地读取Mike Ash。对于Swift代码

如果您需要了解问题,Mike Ash是好的,对于Swift代码,请查看this question - 阅读所有答案评论。

HTH