2017-05-08 57 views
0

我有一个JSON,通过它我可以得到板子列表。可以通过self.jsonGame.boards访问。现在我必须调用所有这些电路板并显示它的内容。DispatchQueue.main.async的多个请求在swift中不能正确执行3

但是电路板并没有被一致地调用。他们有时只会出现。

func fetchBoard(){ 

    let repo = GameRepository() 
    let prefs = UserDefaults.standard 
    if self.jsonGame.boards.count > 0 { 
     self.sortedBoardArr.reserveCapacity(self.BoardArr.count) 

     for board in self.jsonGame.boards{ 

      DispatchQueue.main.async 
      { 
        repo.GetBoardInfo(gameID: self.jsonGame.Id, boardID: board , completion : {(response , errorCode) -> Void in 

         if errorCode == ErrorCode.NoError{ 
          DispatchQueue.main.sync { 

           self.BoardArr.append(response) 
           self.sortArr() 
           self.collectionView.reloadData() 

          } 
         } 

        }) 
      } 
     } 
    } 
} 

func sortArr(){ 
    if self.jsonGame.boards.count == self.BoardArr.count{ 
     for board in self.jsonGame.boards{ 
      for boardarr in self.BoardArr{ 
       if boardarr.id == board{ 
        self.sortedBoardArr.append(boardarr) 
       } 
      } 
     } 
    } 
} 

如果任何人都可以帮助我弄清楚如何确保电路板被调用的一致性。

我很喜欢异步处理。抱歉,添麻烦了。

+0

你试图使用main请求GetBoardInfo。为什么不背景或其他线程? – iWheelBuy

+0

因为我无法找到后台任务已完成。所以认为保持简单,并在主要的异步本身执行。 – Prateekro

回答

2

我有一个类似的问题,我填充了一个数组,其元素来自不同的异步网络请求,当请求同时运行时,我的数组的最终大小取决于并发任务的执行。

我设法解决我的问题,使用串行队列和调度组。 这是我会怎样改变你的代码:

func fetchBoard(){ 

    let repo = GameRepository() 
    let prefs = UserDefaults.standard 
    if self.jsonGame.boards.count > 0 { 
     self.sortedBoardArr.reserveCapacity(self.BoardArr.count) 
     let serialQueue = DispatchQueue(label: "serialQueue") 
     let group = DispatchGroup() 
     for board in self.jsonGame.boards{ 
      group.enter() 
      serialQueue.async { 
       repo.GetBoardInfo(gameID: self.jsonGame.Id, boardID: board , completion : {(response , errorCode) -> Void in 
        if errorCode == ErrorCode.NoError{ 
         self.BoardArr.append(response) 
        } 
        group.leave() 
       }) 
       DispatchQueue.main.async{ 
        group.wait() 
        self.sortArr() 
        self.collectionView.reloadData() 
       } 
      } 
     } 
    } 
} 

这2个答案在这里类似的问题上堆栈溢出是相当有帮助的我,当我有一个类似的问题:Blocking async requestsConcurrent and serial queues

+0

工程就像一个魅力。非常感谢。在过去的6天里停滞不前。 :) – Prateekro

+0

似乎,有'self.BoardArr.append(response)'行中的数据竞赛。另外'serialQueue'的使用对我来说似乎没有意义。并且,用'group'阻止主线程。等待也不是一个好主意。 :)您应该将'self.BoardArr.append(response)'语句提交到一个专用队列中 - 可能是主队列,并且只需在for循环外调用'group.notify'并在主队列中提交一个块。 – CouchDeveloper

+0

当我在多个网络请求的完成块中同时向阵列中添加元素时,我遇到了问题,因此也是串行队列。在这种情况下,group.notify可能会起作用,但是我发现group.wait更健壮,除非您需要在主线程上执行其他计算或从其他来源更新UI。 –