2017-12-07 4 views
1

Multipeer Connectivityフレームワークを使用してセッションからデータを受け取ったときに、データを更新してテーブルをリロードしたいという問題に苦労しています。ビューコントローラの瞬時にここでMultipeer Connectivity(Swift 3)を使用したセッションでdidReceiveData()によってtable.reloadDataを呼び出す方法

はMPCHandlerのdidReceiveData機能のための私のコードです:WinnerDataController

func syncWinnerFromDictionary(d: NSDictionary){ 
    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let context = appDelegate.persistentContainer.viewContext 
    let entityDescription = NSEntityDescription.entity(forEntityName: "Winner", in: context)! 

    let winner: Winner = NSManagedObject(entity: entityDescription, insertInto: context) as! Winner 
    winner.setValue(d.value(forKey: "index"), forKey: "index") 
    winner.setValue(d.value(forKey: "dept"), forKey: "dept") 
    winner.setValue(d.value(forKey: "name"), forKey: "name") 
    save() 
    appDelegate.resultViewController.tableView.reloadData() 
} 

での同期機能については

func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) { 
    NSLog("%@", "didReceive: \(data)") 
    if var dict: [NSDictionary] = NSKeyedUnarchiver.unarchiveObject(with: data) as? [NSDictionary]{ 
     let d = dict.removeFirst() 
     let appDelegate = UIApplication.shared.delegate as! AppDelegate 
     appDelegate.winnerDataController.syncWinnerFromDictionary(d: dict) 

    } 
} 

私はデータの受信時にresultViewContollerのテーブルを更新し、再ロードします。しかし、appDelegate.resultViewController.tableView.reloadData()に行くと、コンソールはfatal error: unexpectedly found nil while unwrapping an Optional valueを出します。私は一日中、tableViewが無限である理由を理解していましたが、まだ何も考えていませんでした。

誰かが助けてもらえますか? Thx

結果ビューコントローラで@Hitesh Sultaniya:NotificationCenter.default.addObserver(self, selector: #selector(testing), name: NSNotification.Name(rawValue: "syncWinner"), object: nil)func testing(notification: Notification){ print("testing") self.tableView.reloadData() }が提供する次のコードを試しました。また、WinnerDataControllerのNotificationCenter.default.post(name: NSNotification.Name(rawValue: "syncWinner"), object: nil)

コンソールでは、「テスト」が表示されます。ただし、数秒後に "このアプリケーションは、メインスレッドからエンジンにアクセスした後、バックグラウンドスレッドから自動レイアウトエンジンを変更しています。これはエンジンの破損や異常なクラッシュにつながります。" が表示されます。

func testing(notification: Notification){ 
DispatchQueue.global(qos: .userInitiated).async{ 
    self.tableView.reloadData() 
} 

}

は現在、エラーが示されていない:

そして、私はこれを試みました。しかし、表には、まだ、まだ...再読み込みされていないあなたがテーブルビューにリロードする通知オブザーバを設定することができresultViewControllerで

答えて

1

あなたはこのよう

//レジスタに設定し、結果ビューコントローラ

にオブザーバを追加することができます

NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTableView(_:)), name: NSNotification.Name(rawValue: "<Your Notfication Name>"), object: nil) 

// handle notification 
func reloadTableView(_ notification: NSNotification) { 

    //relaod your table view 
} 

そして、あなたがデータを受信して​​行われたとき、あなたはこの

NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil) 
のような通知を投稿することができます

だから、これはあなたが結果ビューコントローラに設定していると、あなたのタスクは

注意を実行されます通知掲載します:これは、アプリケーションがUIがどこということに変更することならばそのエラー

が含まれている場合があり、単に擬似コードですあなたはこのタスクを実行中にUIを変更します そして、私はあなたがあなたのコードで直接あなたがテーブルを再読み込みしているあなたのコードに従って、テーブルビューを再ロードする前に再びデータベースからデータをフェッチする必要があると思います。 あなたは

if (Thread.isMainThread == true) 
{ 
        //Perform UI Task 
} 
else 
{ 
     //Dispatch for main queue with synchronous not asynchronous and then update the UI 
} 

が@Hitesh Sultaniyaの助けを借りて、これは

+0

ご協力いただきありがとうございます。しかし、それは動作しません – lulusen

+0

ありがとう!できます – lulusen

0

をホープ、このような現在のスレッドを確認することができ、私は問題を解決しました。私はResultViewControllerでこれを試みたが、動作しません、最初

override func viewDidLoad() { 
    super.viewDidLoad() 
    NotificationCenter.default.addObserver(self, selector: #selector(testing), name: NSNotification.Name(rawValue: "syncWinner"), object: nil) 
    appDelegate = UIApplication.shared.delegate as! AppDelegate 
    } 

func testing(notification: Notification){ 
    if Thread.isMainThread == true{ 
     self.tableView.reloadData() 
     print("main thread") 
    } 
    else{ 
     DispatchQueue.main.sync { 
      self.updateList() 
      print(winnerList.count) 
      self.tableView.reloadData() 
      print("not main thread") 

     } 
    } 

同期機能についてWinnerDataControllerに:ResultViewControllerについては

func syncWinnerFromDictionary(d: NSDictionary){ 
    let appDelegate = UIApplication.shared.delegate as! AppDelegate 
    let context = appDelegate.persistentContainer.viewContext 
    let entityDescription = NSEntityDescription.entity(forEntityName: "Winner", in: context)! 
    let winner: Winner = NSManagedObject(entity: entityDescription, insertInto: context) as! Winner 
    winner.setValue(d.value(forKey: "index"), forKey: "index") 
    winner.setValue(d.value(forKey: "dept"), forKey: "dept") 
    winner.setValue(d.value(forKey: "name"), forKey: "name") 
    save() 
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "syncWinner"), object: nil) 

ここ

は仕事の私のコードです

override func viewDidLoad() { 
    super.viewDidLoad() 
    NotificationCenter.default.addObserver(self, selector: #selector(testing), name: NSNotification.Name(rawValue: "syncWinner"), object: nil) 
    appDelegate = UIApplication.shared.delegate as! AppDelegate 
    } 

func testing(notification: Notification){ 
    if Thread.isMainThread == true{ 
     self.tableView.reloadData() 
     print("main thread") 
    } 
    else{ 
     DispatchQueue.main.sync { 
      self.tableView.reloadData() 
      print("not main thread") 

     } 
    } 

DispatchQueue.main.syncのブロックを実行すると、メインスレッドではなく、最新のwinnerListが取得されていないためです。実際には、テーブルはまだ古いwinnerListでリロードされています。したがって、まだリロードされていないテーブルのようです。

次に、このスレッドに最新のコアデータを取得させるためにself.updateList()を追加しました。最後に、それは動作します。

これは、私と同じ問題で苦労している人にとっては役に立ちます。

関連する問題