-1

Swift 3(Xcode 8.3.2)のswitch文を使用して、swissySSONを使用してMacOSアプリケーションを解析しています。それぞれのケースについて、同じクラス(NSViewController)で宣言されているテキストビューへの更新を印刷しようとしていて、関連するストーリーボードに@IBOutletを使用してバインドしています。DispatchQueueを使用してswitchステートメントからNSTextViewを更新する際の遅延を修正する

私はtextViewを更新し、その関数(func addLogToConsoleWindow(newLogEntry: String) {})をtextViewに印刷する関連テキストで呼び出すための関数を宣言しました。

関連するコードは、次のとおり

@IBOutlet var textViewActivityLog: NSTextView! // Create an outlet for the activity log view 

.............

 for jsonObj in arrayOfJSONObjects { 
     if jsonObj != JSON.null { 


      // Use a switch statement to select the correct Class to use for storing the appropriate event 

      switch jsonObj["event"].string! { 
      case "Docked": 
       arrayOfDockedEvents.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "Docked event being parsed") 
      case "FSDJump": 
       arrayOfFSDJumpEvents.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "FSD Jump event being parsed") 
      case "Progress": 
       arrayOfProgressEvents.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "Commander's progress being parsed") 
      case "Rank": 
       arrayOfRankEvents.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "Rank information being parsed") 
      case "LoadGame": 
       arrayOfLoadGameEvents.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "Game load details being parsed") 
      case "StartJump": 
       arrayOfStartFSDJumps.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "Start FSD Jump event being parsed") 
      case "MiningRefined": 
       arrayOfMiningRefined.append(jsonObj) 
       self.addLogToConsoleWindow(newLogEntry: "Mining event being parsed") 
      default: 
       if !setOfEventType.contains(jsonObj["event"].string!) { 
        self.addLogToConsoleWindow(newLogEntry: "\((jsonObj["event"].string!)) event discovered but not parsed") 
       } 
      }     
     } else { 
      print("Haven't been able to find a jsonObj") 
     } 
    } // END OF 'for jsonObj' 

...........

@objc func addLogToConsoleWindow(newLogEntry: String) { 
     textViewActivityLog.string? = "\n" + newLogEntry + (textViewActivityLog.string)! 
     textViewActivityLog.scrollRangeToVisible(NSMakeRange(0, 0)) 
} // END OF addLogToConsoleWindow() 

私が探している動作は、特定のケースにアクセスした直後にtextView(textViewActivityLog.string?)を更新することです。

ただし、textViewはすぐには更新されません。 for jsonObj in arrayOfJSONObjects {}のループが完了した後でのみ更新されます。これは、forループが実行されるのと同時に、数千のテキスト行が同時に表示されることを意味します。

func addLogToConsoleWindow(newLogEntry: String) {}関数が呼び出されたコードのポイントで、textViewを更新するにはどうすればよいですか?

喜んで受け取ったアドバイスやガイダンス。関連する以前の質問を見つけることができませんでした。

+0

バックグラウンドスレッドでJSONを解析し、メインスレッドのテキストビューを更新します。 – Willeke

+0

ありがとう - それは私を超えています。だからいくつかの研究と私は報告します。 – Wolfstar

+0

質問がなぜ書き下されたのか分かりません。なぜ私は学ぶことができるか、誰かに助言することができますか? – Wolfstar

答えて

0

を、私は

DispatchQueue.main.sync returning exc_bad_instruction Swift 3)この応答を読んだ後、私が持っていた行動の問題を解決し、私は次のように作られました

func addLogToConsoleWindow(newLogEntry: String) { 
    DispatchQueue.global().async (execute: { 
     DispatchQueue.main.sync { 
      self.textViewActivityLog.string? = "\n" + ":-> " + newLogEntry + (self.textViewActivityLog.string)! 
      self.textViewActivityLog.scrollRangeToVisible(NSMakeRange(0, 0)) 
     } 
    }) 
} // END OF addLogToConsoleWindow() 

トリックを行っているようだ:addLogToConsoleWindow(newLogEntry: String) {}機能への変更。

回答した方々に感謝します。あなたのマルチスレッド化に関する指針が参考になりました。

1

Willekeが言ったように、あなたがそのようなこと行うことができます。興味のある方のために

switch jsonObj["event"].string! 
{ 
    case "Docked": 
     arrayOfDockedEvents.append(jsonObj) 
     self.addLogToConsoleWindow(newLogEntry: "Docked event being parsed") 
    case "FSDJump": 
     arrayOfFSDJumpEvents.append(jsonObj) 
     self.addLogToConsoleWindow(newLogEntry: "FSD Jump event being parsed") 

     //do on main thread... 
     DispatchQueue.main.async 
     { 
      //updating text on label or other textview 
     } 

    case "Progress": 
     arrayOfProgressEvents.append(jsonObj) 
     self.addLogToConsoleWindow(newLogEntry: "Commander's progress being parsed") 
    // ... 
    default: 
    if !setOfEventType.contains(jsonObj["event"].string!) 
    { 
     self.addLogToConsoleWindow(newLogEntry: "\((jsonObj["event"].string!)) event discovered but not parsed") 
    } 
} 
+0

こんにちはエドモンド - それは働いていないようです。 DispatchQueue.main.async内のself.addLogToConsoleWindow(newLogEntry: "Docked event being parsed")ステートメントをカプセル化し、動作に何の変更も加えていません – Wolfstar

+0

ご迷惑をおかけして申し訳ありません。実際の問題を見つけるための完全なコードを見る必要があります。 –

+1

私はそれに取り組んで、まずそれを解決できるかどうかを見ていきます。学習する最善の方法。 – Wolfstar

関連する問題