2016-09-04 2 views
2

私はいくつかのサンプルコードをobjective-cからswiftに翻訳しようとしています!不正なアクセス、マルチスレッド、GCD、スウィフト

このシミュレーションには重大なマルチスレッド部分を除いて、すべて機能しています。

何らかの理由で、複数のスレッドを使用するとアクセスエラーが発生します。配列から物事を取得または設定するときは、特に注意してください。

このクラスは静的クラスの内部でインスタンス化されています。

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

同じ配列をacesses、右のこの1の後に別のスレッドで実行する必要があります別のループもあることに注意することが重要です。それはまだ別のスレッドで2番目を持っていないので、それはまだ悪いacessと言われているので、私はそれが表示するirrelivantだと感じている。

もしあなたが私のことを教えていただけたら、このクラッシュが最初からむしろランダムな時間に起こる原因を教えてください。

あなたが参照したい場合はここでの目的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座標がクラッシュが一貫しているかどうかを調べるために処理していたことを確認できました。確かに、それは1fps以下にfpsを下げましたが、私はまだクラッシュしていないことに気付きました。プログラムは今のところ1fps以下の悪影響なしに完璧に動作しています。

+0

これは私にとっては悪い言葉でしたが、Appleはコードを書きましたが、それは目的のcです。私は言葉を修正した。 –

+0

バックトレースを提供することはおそらく役に立つでしょう... – jcaron

+0

@jcaron私はバックトレースの一部であると信じているものの絵を追加しました。それは役に立ちますか? –

答えて

3

AppleコードはCスタイルの配列を使用していますが、これはAppleコードのように適切に使用すると「スレッドセーフ」です。

スウィフト、およびObjective-Cの配列はではなく、スレッドセーフであり、これが問題の原因です。配列への何らかのアクセスコントロールを実装する必要があります。

単純な方法は、GCDシーケンシャルキューを各アレイに関連付けて、このキューに対して非同期ディスパッチ配列に書き込み、ディスパッチ同期を読み取ることです。これはシンプルですが、並行性が減り、Mike Ashを読みやすくなります。スウィフトコードについて

マイクアッシュは、あなたが問題を理解する必要がある場合は良好で、スウィフトコードのためのあなたとthis questionを見て - すべての答えを読んコメント。

HTH

+0

感謝していただきありがとうございます!それは私が質問の一番下に置いた異常を説明することはできませんが、それはたぶん異常です。私はそれを0.5 fpsよりずっと速く動かす必要があります。NSArraysがスレッドセーフであると言っているドキュメント(https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html)を見ましたが、それは迅速で同じですか? –

+0

また、スレッドセーフな配列をクラス内の静的メソッドとして使用していたとしても、それでもスレッドセーフなのでしょうか? –

+0

一般に、不変型/値はスレッドセーフでなければなりません。 'NSArray'または' let v = array value'を返します。スレッドの安全性は静的メソッドの使用によって影響されるべきではありません。おそらく何かをスレッドセーフにするかどうかを研究し、これらのような質問に答えることを理解する必要があります。 – CRD

関連する問題