Dispatch async和ViewWillAppear

时间:2016-12-12 03:29:02

标签: ios swift grand-central-dispatch

我正在开发iOS应用程序并遇到了一个问题,这个问题正在耗费我的时间来理解。我不能把所有的源代码放在这里,但我试图把它与问题有关。

 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对象。

基于某些业务逻辑,当我从parentViewController调用“updateMyProductList”方法时,我得到下面的方法调用序列。

  1. 从ParentViewController调用updateMyProductList
  2. updateMyProductList get called
  3. “在这里更新数据源数组代码”从“updateMyProductList”方法调用
  4. viewWillAppear被调用
  5. 这里我希望在第3步之后,“dispatch_async”块中的代码应该得到重新加载表视图的调用。我不确定为什么要调用“viewWillAppear”。如果在“dispatch_async”之后调用“viewWillAppear”,我很好。

    这里dispatch_async(dispatch_get_main_queue()块代码的优先级低于“viewWillAppear”?因为两者都在主线程中?

    如果我得到一些提示来解决这个问题,那将会非常有帮助。

3 个答案:

答案 0 :(得分: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()
         }
      }
    } 
}

答案 1 :(得分:0)

你的问题很清楚细节,但听起来你的异步调用是在调用viewWillAppear之后返回的。

我建议将您的网络代码移动到专用的单一类来处理所有网络调用,然后让您的视图加载,使其快速加载并优雅地等待新数据(即活动指示符)。然后,当新数据返回时,您更新视图。

答案 2 :(得分:-1)

我从来没有用那种语言为iOS编写过任何内容,但根据我的经验,我可以告诉你,在父类上调用updateMyProductList而不是在你的类上,这显然会调用你的viewWillAppear。 :)。我想你必须覆盖 updateMyProductList的方式相同:

override func updateMyProductList() {..}

如果您的方法从未被调用过,我认为您无法进行调度:)。如果在viewWillAppear之后执行,则必须同步它们。