Как мне решить эту проблему: UILabel.text должен использоваться только из основного потока - PullRequest
1 голос
/ 31 октября 2019

Поэтому я пытаюсь обновить пользовательский интерфейс в моем приложении. Что происходит, так это то, что метки обновляются, но когда они не сохраняют свое значение, а иногда принимают значение другой метки. Кроме того, я получаю сообщение, что метка должна использоваться только из основного потока, как мне решить эту проблему?

Вот мой код:

let queue = DispatchQueue(label: "update")
queue.async {
   for s in self.fietshare.stands {
      for b in s.bikes {
         lbAvailable.text = "Available Bikes: " + String(s.id) +  "  " + String( s.bikes.count) // shows too big numbers
         nrOfAvailable.text =  String(b.distance) + "M"
         annotationView.layoutIfNeeded()
         print(s.id)
         print("Nr of bikes")
         print(s.bikes.count)
      }
   }
}

DispatchQueue.main.async {
   self.view.backgroundColor = . black;
   self.view.layoutIfNeeded()
}

if (Thread.current.isMainThread) {
    print("Main thread")
}

1 Ответ

1 голос
/ 31 октября 2019

Попробуйте это

let queue = DispatchQueue(label: "update")

queue.async {

    var available = ""
    var nrOfAvailable = ""
    for s in self.fietshare.stands{
        for b in s.bikes {
            available = available + "Available Bikes: " + String(s.id) +  "  " + String( s.bikes.count) // shows too big numbers
            nrOfAvailable = String(b.distance) + "M"

            print(s.id)
            print("Nr of bikes")
            print(s.bikes.count)
        }
    }

    // UPDATE UI after all calculations have been done
    DispatchQueue.main.async {
        lbAvailable.text = available
        nrOfAvailable.text = nrOfAvailable
        annotationView.layoutIfNeeded()

        self.view.backgroundColor = . black;
        self.view.layoutIfNeeded()
    }
}

Объяснение:

  • вы запускаете асинхронную задачу с queue.async
  • внутри этой «фоновой работы», которую вы запускаетецикл for
  • для цикла for необходимо обновить некоторые биты пользовательского интерфейса
  • сделать это в основном потоке, поэтому мы переключаем эту часть обратно в основной поток

Объяснение 2:

  • UIKit не является потокобезопасным. Это означает, что все изменения ожидаются от основного потока и будут синхронными (одно за другим). Таким образом, нет никакого «запирающего механизма» или защиты. Если вы попытаетесь изменить метку из разных потоков одновременно, могут произойти странные вещи из-за условий гонки, таких как изменяемые части метки, в другом порядке и т. Д.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...