2016-01-08 5 views
1

Я установил ярлык и индикатор прогресса, чтобы привязать его к свойству progress AppDelegate. Затем я выполняю работу в параллельной очереди. По мере завершения каждой задачи я увеличиваю прогресс на 1.Индикатор прогресса не анимируется

Моя проблема заключается в том, что этикетка обновляется по тику, как ожидалось, но индикатор прогресса не работает. Он обновляется каждые 15 тиков или около того. Любая идея, как заставить индикатор прогресса двигаться с каждым тиком?

Упрощенный пример:

class AppDelegate: NSObject, NSApplicationDelegate { 
    dynamic var progress = 0 

    @IBAction func updateProgress(sender : AnyObject) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
      guard self.progress < 100 else { 
       return 
      } 

      self.progress += 1 
      sleep(1) 
      self.updateProgress(sender) 
     } 
    } 
} 

ответ

1

По моему опыту, обновление переменной привязки из фоновой очереди иногда приводит к смешному поведению. Примером может служить индикатор прогресса, который не обновляется. Тем не менее, я не понял часть «почему». Мое обходное решение - сделать вашу работу в фоновом режиме, но обновить переменную привязки в главной очереди.

Попробуйте это (не проверено):

@IBAction func updateProgress(sender : AnyObject) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
     guard self.progress < 100 else { 
      return 
     } 

     dispatch_async(dispatch_get_main_queue()) { 
      self.progress += 1 
     } 

     sleep(1) 
     self.updateProgress(sender) 
    } 
} 

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

+0

Спасибо, сейчас работает! – Jenny

0

Изменения в пользовательском интерфейсе должно быть обновление в главном потоке. Вы должны перенести ход обновления в основной поток.

dispatch_async(dispatch_get_main_queue()) { 
    self.updateProgress(sender) 
} 
+0

Спасибо за ваш ответ. Причина, по которой я использовал привязку Cocoa, - использовать KVO для одновременного обновления нескольких элементов управления. Почему это работает для одного элемента управления, но не для другого? – Jenny

+0

Я думаю, вы можете прочитать это http://stackoverflow.com/questions/12693197/dispatch-get-global-queue-vs-dispatch-get-main-queue –

+0

Это плохой совет. Если 'updateProgress' занимает много времени, он заблокирует вашу основную очередь и заморозит ваш пользовательский интерфейс. –

Смежные вопросы