2016-12-12 8 views
0

Я работаю над приложением iOS и пришел к одной проблеме, которая ест мое время, чтобы понять. Я не могу поместить весь исходный код здесь, но я пытаюсь установить, что связано с проблемой.Отправка async и ViewWillAppear

class MyItemsListVC: UIViewController, UITableViewDataSource,UITableViewDelegate { 

    override func viewWillAppear(animated: Bool) { 
     super.viewWillAppear(animated) 
    } 


    func updateMyProductList() { 

    //update data source array code here 

     dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       productListTableView.reloadData() 
     }) 


    } 
} 

У меня есть один parentViewController (UIViewController) из указанного класса, который содержит объект своего объекта childViewController MyItemsListVC т.е..

На основе некоторой бизнес-логики, когда я вызываю метод updateMyProductList из parentViewController, я получаю ниже последовательность вызовов метода.

  1. Призыв к updateMyProductList из ParentViewController
  2. updateMyProductList дозвонились
  3. "Обновление источника данных код массива здесь" от метода "updateMyProductList" дозвонились
  4. viewWillAppear дозвонились

Здесь я ожидая после третьего шага, код внутри блока «dispatch_async» должен получить вызов, который перезагружает представление таблицы. Я не уверен, почему вызываются «viewWillAppear». Я в порядке, если «viewWillAppear» вызывается после «dispatch_async».

Здесь же dispatch_async (dispatch_get_main_queue() блок кода, имеющий низкий приоритет над «viewWillAppear»? Так как в главном потоке?

Это будет очень полезно, если бы я получить некоторые подсказки, чтобы решить эту проблему.

ответ

0

Итак, почему этот метод не работает? Вы не указали?

Советуем вам создать отдельный класс для обработки вызовов data/api. Создайте массив для хранения данных в этом классе , установите его в internal, чтобы вы могли получить доступ к массиву в других классах. некоторый фрагмент кода, который вы можете прочитать.

class APIManager : NSObject { 
    static let sharedInstance = APIManager() 
    typealias NerfireAPICompletionBlock = (_ value: AnyObject?, _ error: NSError?) -> Void 
    internal var dataArray = Array() 
    internal func callServerToFetchNewData(){ 
     //call api and store data to dataArray 
     if error != nil { 
      completion(nil, error as NSError?) 
     } else { 
      completion(true as AnyObject?, nil) 
     } 
    } 
} 

class MyItemsListVC: UIViewController, UITableViewDataSource,UITableViewDelegate { 

    override func viewWillAppear(animated: Bool) { 
     super.viewWillAppear(animated) 
    } 

    func updateMyProductList(completion: @escaping NerfireAPICompletionBlock) { 

    //update data source array code here 

     APIManager.sharedInstance.callServerToFetchNewData(){ success, error -> Void in 
     if error != nil { 
      print(error?.description) 
     } else { 
      productListTableView.reloadData() 
     } 
     } 
    } 
} 
+0

У меня есть отдельный класс для извлечения данных ... Моя проблема в том, почему «viewWIllAppear» получает вызов перед кодом внутри dispatch_async i.e.? имеет ли он более высокий приоритет в последовательной очереди?Я хотел бы запустить первый код внутри блока dispatch_async до того, как viewwillappear и после того, как массив источников данных будет обновлен. –

-1

Я никогда не писал ничего для прошивки на этом языке, но из моего опыта, я могу вам сказать, что updateMyProductList вызывается на родительский классе не по вашим, что, очевидно, вызывает ваш viewWillAppear. :). Я думаю, вы должны переопределить updateMyProductList таким же образом:

override func updateMyProductList() {..} 

Я не думаю, что вы можете получить к отправке, если ваш метод никогда не вызывается :). Если он выполняется после viewWillAppear, вы должны синхронизировать их.

0

Ваш вопрос освещен по деталям, но похоже, что ваш асинхронный вызов возвращается после ваш видWillAppear называется.

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

+0

У меня есть класс сети, который обрабатывает веб-службу и отправляет уведомление на основе результата ... при успешном вызове updateProdcutList, но проблема в том, что некоторые пользовательские интерфейсы который вызывает вызов viewWillAppear в то же время ... проблема в том, что он получает вызов после того, как источник данных получает обновление ... Короче, он получает приоритет перед отправкой асинхронного блока, из-за которого он получает вызов после просмотраWillAppear –

+0

Хорошо, тогда не вызывайте свой updateProduct from viewWillAppear. Обновите свой пользовательский интерфейс из результата вызова aysnc, а в viewWillAppear просто отобразите экран загрузки – Chris