2017-09-24 92 views
2

該函數初始化GMSMarkers:無法更新UI

func makeMarkers (progressHandler: ((String) -> Void)? = nil) { 
    progressHandler?("Инициализируем маркеры...") 
    for device in self.devices { 
     progressHandler?("Инициализируем маркеры: для устройства \(device.name!)...") 
     if let position = self.positions.findById(device.positionId) { 
      if let marker = DeviceMarker(device, at: position) { 
       self.deviceMarkers.append(marker) 
      } 
     } 
    } 
    for geofence in self.geofences { 
     progressHandler?("Инициализируем маркеры: для геометки \(geofence.name!)...") 
     if let marker = GeofenceMarker(geofence) { 
      self.geofenceMarkers.append(marker) 
     } 
    } 

    self.locationManager.requestLocation() 

    progressHandler?("Инициализируем маркеры: для пользователя \(self.loggedUser.name!)...") 
    if let userLocation = self.locationManager.location { 
     self.userMarker = UserMarker(self.loggedUser, at: userLocation) 
    } else { 
     self.userMarker = UserMarker(self.loggedUser, at: CLLocation(latitude: 48, longitude: 44)) 
    } 
    progressHandler?("Маркеры инициализированы...") 
} 

正如你可以看到我想要告訴用戶如何使用progressHandler此操作的進度。

但是在執行該功能期間,我看不到任何消息。 剪斷其中I調用函數makeMarkers:

     ... 
      DB.geofences.server.getAll() { geofences in 
       self.statusLabel.text = "Получили геометки \(geofences.count)..." 
       DB.devices.server.getAll() { devices in 
        self.statusLabel.text = "Получили устройства \(devices.count)..." 
        DB.positions.server.getAll() { positions in 
         self.statusLabel.text = "Получили позиции \(positions.count)..." 

         DB.devices.client.insert(devices) 
         self.statusLabel.text = "Записали устройства..." 
         DB.positions.client.insert(positions) 
         self.statusLabel.text = "Записали позиции..." 
         DB.geofences.client.insert(geofences) 
         self.statusLabel.text = "Записали геометки..." 

         MapManager.shared.makeMarkers() { status in 
          self.statusLabel.text = status 
         } 
         ... 

如果我使用打印改變視圖消息()的所有消息將被顯示。 所以,問題是:爲什麼在執行我的函數期間UI變化被阻止,以及如何擺脫?

更新:當然,我在主線程中做了所有事情。

更新2:我打電話更新我的功能的代碼片段。我在地圖控制器顯示之前看到的最後一條消息是「Получилиустройства...」,這很奇怪,因爲我敢肯定我的位置也是

+0

也許我誤解了語法,但是你不是將你的progressHandler設置爲零嗎? – matiastofteby

+0

您是否試圖強制它在主線程上運行,如 'DispatchQueue.main.async {self.statusLabel.text = status }''statusLabel'顯示「Записалигеометки...」或不是? –

+0

@mathiastofteby:progressHandler設置爲nil聲明函數,這意味着默認值,當我調用我的函數progressHandler不是零。 – zzheads

回答

2

嗯,這是因爲UI更新發生在主線程中。但是,當您更改標籤的文本時,此更改不會立即發生。相反,所有UI更改都會按計劃進行,並且只有當應用程序完成當前通過事件循環時纔會呈現。

由於您在同一個主循環中執行耗時的任務,因此它會被阻塞,並且只有在這些任務完成並且函數返回時纔會進行更改。

您可以檢查這些文章以獲取有關事件如何循環工作更詳細的解釋:Run LoopsMain event loop

我建議你將所有耗時的任務(如數據庫查詢)到後臺線程,並調用主當你真的想更新你的UILabel時,從那裏開始線程。