2016-04-11 2 views
0

Я этот метод:Невозможно выполнить действия в фоновом режиме и обновить progressView в mainThread

func stepThree() { 
    operation = "prDatas" 
    let entries = self.data.componentsSeparatedByString("|***|") 
    total = entries.count 
    for entry in entries { 
     ++current 
     dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { 
      self.registerDB(entry) 
     }) 
    } 
    status.setProgress(Float(current/total), animated: true) 
    finishAll() 
} 

Я хочу, чтобы выполнить registerDB функцию и обновить ProgressBar при завершении. я тестировал несколько путь, но никогда не удастся


EDIT 1

Реализация @Russell предложение, отлично работать, но вычисления значения внутри dispatch_async блока всегда приводит к 0

Есть вопрос о операций и многопоточности?

метод:

func stepThree() { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 
     var current = 0 
     var total = 0 
     self.operation = "prDatas" 
     let entries = self.data.componentsSeparatedByString("|***|") 
     total = entries.count 
     for entry in entries { 
      ++current 
      self.registerDB(entry) 
      dispatch_async(dispatch_get_main_queue(), { 
       print("value of 'current' is :" + String(current)) 
       print("value of 'total' is :" + String(total)) 
       print("Result is : " + String(Float(current/total))) 
       self.updateV(Float(current/total)) 
      }) 
     } 
    }) 
} 

Консоль вывода:

value of 'current' is :71 
value of 'total' is :1328 
Result is : 0.0 
+1

Float (текущий/всего) ваша проблема - расчет делается первый - с целыми числами - а затем результат (который всегда равен 0) преобразуется в Float. У меня была такая же проблема в моем решении, и именно поэтому я преобразовал оба параметра в float first – Russell

+0

Это работает лучше, спасибо еще раз! – Khorwin

ответ

1

Ваш код будет обновлять строку состояния сразу - поэтому работа не будет закончена.

Вам необходимо перенести обновление так, чтобы оно фактически следовало за функцией registerDB, а затем вам нужно сделать вызов в основном потоке. Вот пример - использование фиктивных функции вместо вызовов функций, так что я могу гарантировать, что работает, как ожидалось

func stepThree() 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 
     let total = 5 // test data for demo 
     for entry in 0...total 
     { 
      // dummy function - just pause 
      sleep(1) 
      //self.registerDB(entry) 

      // make UI update on main queue 
      dispatch_async(dispatch_get_main_queue(), 
      { 
       self.setProgress(Float(entry)/Float(total)) 
      }) 
     } 
    }) 
} 

func setProgress(progress : Float) 
{ 
    progressView.progress = progress 
    lblProgress.text = String(format: "%0.2f", progress) 
} 
+0

Это не работает. Я тестировал обновление с помощью функции, вызываемой с помощью функции performSelectorOnMainThread, теперь точки останова показывают мне, что функция вызывается в удобное время, обновляет значение progressView, но не визуально ... – Khorwin

+0

Я обновил ответ выше, обернув весь «stepThree» в фоновая задача и вызовы главной очереди для обновления пользовательского интерфейса изнутри. – Russell

+0

Вы правы, это нормально! Спасибо за это. Я столкнулся с проблемой относительно ценности для прогресса, я обновил свой пост. – Khorwin

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

  • Нет связанных вопросов^_^