2015-05-27 2 views
2

У меня есть ситуация, когда я хочу представить UIAlertController, чтобы дождаться события (асинхронный запрос данных от третьего лица), чтобы закончить, прежде чем показывать мой основной ViewController пользователю для взаимодействия с ,iOS отклоняет UIAlertController в ответ на событие

Как только асинхронный код заканчивается, я хочу отклонить UIAlertController. Я знаю, что обычно UIAlertControllers настраиваются с помощью кнопки, чтобы отклонить ее, которая вводится пользователем. Мне интересно, возможно ли то, что я хочу сделать (увольнение с событием вместо ввода пользователем)?

До сих пор я пытался показать UIAlertController, а затем ждать в цикле при проверке логическое значение для того, когда происходит событие:

var alert = UIAlertController(title: "Please wait", message: "Retrieving data", preferredStyle: UIAlertControllerStyle.Alert) 

self.presentViewController(alert, animated: true, completion: nil) 

// dataLoadingDone is the boolean to check 
while (!dataLoadingDone) { 

} 

self.dismissViewControllerAnimated(true, completion: nil) 

Это дает предупреждение

Предупреждение: Попытка уволить из контроллера просмотра, пока выполняется презентация или увольнение!

и не отклоняет UIAlertController. Я также пробовал alert.dismissViewControllerAnimated(true, completion: nil) вместо self.dismissViewControllerAnimated(true, completion: nil), но это также не избавляет от UIAlertController.

ответ

0

Другой пользователь (матовый) дал то, что я уверен, правильный ответ, но он удалил его, поэтому я собираюсь ответить на него. Просто хотел дать кредит (хотя он, похоже, очень уважаемый в любом случае).

Он написал, что моя презентация UIAlertController не была закончена, прежде чем я попытался ее отклонить, поэтому я получил эту ошибку. Я изменил код на следующее:

// check if I need to wait at all 
if (!dataLoadingDone) { 
     var alert = UIAlertController(title: "Please wait", message: "Retrieving data", preferredStyle: UIAlertControllerStyle.Alert) 

     self.presentViewController(alert, animated: true, completion: {() -> Void in 
      // moved waiting and dismissal of UIAlertController to inside completion handler 
      while (!self.dataLoadingDone) { 

      } 

      self.dismissViewControllerAnimated(true, completion: nil) 
     }) 
    } 

я переместил ожидание и освобождение внутри обработчика завершения вызова presentViewController, так что я знаю, что Представляющий делаются до увольнения. Кроме того, я проверяю, нужно ли мне вообще ждать с первым оператором if, потому что иначе возникает другая проблема, если цикл while никогда ничего не делает.

Я не уверен на 100%, потому что мой логический объект на самом деле никогда не является ложным на данный момент (поиск данных происходит очень быстро). Тем не менее, у меня есть причина полагать, что это займет больше времени в моей разработке приложений, поэтому я буду обновлять ответ здесь, когда у меня есть это.

EDIT: другой пользователь, который ранее отправил ответ (Aaron Golden), также был прав относительно блокировки цикла. Я думал, что цикл while разделяет время обработки с другими событиями, но, по-видимому, не (или, по крайней мере, не хватает времени). Таким образом, вышеуказанный цикл в то время как НЕ работает

+1

Цикл while не нужен и просто растрачивает циклы процессора. Почему бы не сохранить ссылку на UIAlertController и отклонить ее везде, где вы установили self.dataLoadingDone в true? – chedabob

+0

Да, я тоже это осознал. То, что я, по сути, хотел сделать, это дождаться завершения асинхронного запроса и использовать цикл while для ожидания. Тем не менее, это не было необходимо, поскольку его на самом деле просто ждут в любом случае без цикла while =) То, что я закончил (в какой-то момент будет обновлять ответ), зарегистрировало уведомление через NSNotificationCenter для ответа на событие. Таким образом, мне также не нужно логическое. – user3809369

1

Я бы не использовать во время цикла, но didSet наблюдателя вашей dataLoadingDone собственности. Таким образом, вы можете попробовать что-то похожее на следующий код:

class ViewController: UIViewController { 

    var dismissAlertClosure: (() -> Void)? 
    var dataLoadingDone = false { 
     didSet { 
      if dataLoadingDone == true { 
       dismissAlertClosure?() 
      } 
     } 
    } 


    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 

     let alert = UIAlertController(title: "Please wait", message: "Retrieving data", preferredStyle: .Alert) 
     presentViewController(alert, animated: true, completion: nil) 

     // Set the dismiss closure to perform later with a reference to alert 
     dismissAlertClosure = { 
      alert.dismissViewControllerAnimated(true, completion: nil) 
     } 

     // Set boolValue to true in 5 seconds in order to simulate your asynchronous request completion 
     var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))) 
     dispatch_after(dispatchTime, dispatch_get_main_queue(), { self.dataLoadingDone = true }) 
    } 

} 
+0

hmmm ...Я думаю, что я немного смущен вашим примером. Не могли бы вы добавить еще несколько комментариев, чтобы объяснить, что вы делаете? В частности, я смущен, когда замыкается вызов, и часть didSet также – user3809369

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

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