2015-06-24 2 views
0

Я отправляю некоторые данные на свой сервер, и после ответа я отклоняю свой контроллер представления. В представлении viewControllerWillDisappear() я пытаюсь отклонить клавиатуру.Swift: проблема с Threading с помощью DismissViewController() и отключающей клавиатуры

Если текущий viewController viewer не является контроллером корневого представления, я получаю исключение "[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] может вызываться только из основного потока. '". Я попытался вызвать функцию, которая отклонила клавиатуру, а затем viewcontroller (устраняя необходимость viewwilldisappear()), но у нее такая же проблема.

Код: // внутри представлены ViewController

override func viewWillDisappear(animated: Bool) 
    { 
      super.viewWillDisappear(animated) 
      self.view.endEditing(true) 
    } 

Код: // в Presenter ViewController

func manage_response(//) 
    { 
      run_on_background_thread 
      { 
        self.parse(//) 
        run_on_main_thread 
        { 
          self.presented_controller.dismissViewControllerAnimated(true, completion: nil) 

        } 
      } 
    } 

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

Edit:

Синтаксис для задней функции метод я использую для нарезания резьбы:

func run_on_background_thread(code:() -> Void) 
{ 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), code) 
} 

func run_on_main_thread(code:() -> Void) 
{ 
     dispatch_async(dispatch_get_main_queue(), code) 
} 

Решение:

Я отслеживал проблему вниз. Случай отличается от предыдущей мысли. Это происходит, когда я пытаюсь отобразить UIAlertController (через presentViewController), потому что запрос не возвращает правильные данные/учетные данные.

run_on_main_thread 
      { 
        if let controller = visibleViewController() //recursive 
        { 
          controller.view.endEditing(true) 
          controller.presentViewController(alert, animated: true, completion: nil) 
        } 
      } 
+0

Где указано run_on_background_thread и run_on_main_thread? –

+0

Мой плохой. Они определяются глобально в файле вспомогательных/удобных функций. Включено сейчас. Примечание: они работают отлично в течение довольно сложного приложения, только когда клавиатура должна быть уволена, а что-то не так. – Ryan

ответ

0

Проблема заключалась в отображении UIAlertViewController. Эта логика/код разрешит такую ​​проблему:

run_on_main_thread 
{ 
    if let controller = visibleViewController() //recursive 
    { 
     controller.view.endEditing(true)  
     controller.presentViewController(alert, animated: true, completion: nil) 
    } 
} 
0

Вы должны попытаться уволить его в основную очередь так:

dispatch_async(dispatch_get_main_queue()) { self.presented_controller.dismissViewControllerAnimated(true, completion: nil) }

+0

Я делаю именно это, что дает мне исключение. – Ryan

+0

Даже если вы используете вместо dispatch_async, dispatch_sync? – Anand

+0

Есть много минусов с dispatch_sync; при работе с пользовательским интерфейсом, как правило, многие обновления будут происходить асинхронно, и поэтому я лично считаю эту плохую практику. – Ryan

0

Вы получили правильное общее представление, но то, что вы опубликовали это псевдо-код. Дьявол кроется в деталях. Если вы получаете сообщение об ошибке, то где-то ваш код делает вызовы UIKit из фонового потока.

У NSThread есть метод класса isMainThread(). Вы можете использовать это, чтобы проверить, какой код выполняется из фона.

+0

просто аргументы manage_response() и parse() опущены. Я буду обновлять с помощью трейлинг-вызовов функций, которые я использую для run_on_main_thread и run_on_background_thread – Ryan

+0

Я предполагаю, что у вас есть неправильное предположение где-то.У вас есть блок завершения, который, по вашему мнению, выполняется в основном потоке, но это не так, он запускается в потоке BG. В этом блоке завершения вы выполняете код пользовательского интерфейса. Урон уже сделан, и код, который вы отправляете, не является источником проблемы. используйте вызов 'NSThread.isMainThread()' всех ваших блоков/обработчиков завершения, чтобы увидеть, какой код работает в основном потоке, а что нет. –

+0

Я отследил проблему. Случай отличается от предыдущей мысли. Это происходит, когда я пытаюсь отобразить UIAlertController (через presentViewController), потому что запрос не возвращает правильные данные/учетные данные. run_on_main_thread { если пусть контроллер = visibleViewController() // рекурсивный { controller.view.endEditing (истина) controller.presentViewController (предупреждение, анимированные: истинное, завершение: ноль) }} – Ryan

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