2017-08-20 44 views
0
func loadYelpComments(){ 
     guard let business = business else {return} 
     guard let _ = tableView else {return} 
     guard let businessID = business.id else {return} 
     let dateFormatter = DateFormatter() 
     dateFormatter.dateStyle = .full 

     HTTPHelper.getYelpComments(for: businessID, completionHandler: { data in 
      let json = JSON(data) 
      let reviews = json["reviews"].arrayValue.map({return $0.dictionaryValue}) 
      var commentDate: Date? 


      for (index, review) in reviews.enumerated(){ 
       let userDictionary = review["user"]?.dictionary 
       if let dateString = review["time_created"]?.stringValue{ 
        commentDate = dateFormatter.date(from: dateString) 
       } 

       let yelpComment = YelpComment(rating: review["rating"]?.intValue, userImageURL: userDictionary?["image_url"]?.stringValue, userName: userDictionary?["name"]?.stringValue, comment: review["text"]?.stringValue, commentDate: commentDate, commentPageURL: review["url"]?.stringValue) 

       self.comments.append(yelpComment) 
      } 

      print("Number of comments: \(self.comments.count)") //Prints: Number of comments: 3" 
      self.tableView.reloadData() 

     }) 

      print("Number of comments: \(self.comments.count)") //This prints firt "Number of comments: 0" 

    } 

getYelpComments(for:completionHandler:)類方法負責從Yelp API中獲取JSON數據。令我驚訝的是,即使comments實例數組正在通過向其添加新的YelpComment對象而被更新,其count在閉包內部和外部具有不同的值。爲什麼實例變量在閉包內有不同的值?

這些註釋應該顯示在表格視圖中。更令我困惑的是,當我在閉包中添加tableView.reloadData()時,我得到一個index out of bounds for an empty array錯誤,但是當我在閉合一側添加相同的代碼行:tableView.reloadData()時,我沒有發生錯誤,comments.count等於零。任何幫助將非常感激!

P.S.我不知道提及這是否會有所作爲,但data@escaping。我也使用SwiftyJSONAlamofire

UPDATE:

我的表視圖數據源的方法是:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

     if section == 0 { 
      return super.tableView(tableView, numberOfRowsInSection: section) 
     } else { 
      return comments.count 
     } 

    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

     if indexPath.section == 0 { 
      return super.tableView(tableView, cellForRowAt: indexPath) 
     } else { 
      let cell = tableView.dequeueReusableCell(withIdentifier: CustomCellTypeIdentifiers.YelpCommentCell, for: indexPath) as! YelpCommentCell 
      cell.configureYelpCell(with: comments[indexPath.row]) 
      return cell 
     } 
    } 
+0

'getYelpComments'是一個異步調用。在cloure外部的打印語句在閉包中的代碼運行之前執行。發佈你的'cellforRow'和'noOfRowsInSection'方法,我認爲這些方法正在導致崩潰.. – Bilal

+0

@Bilal更新我的問題與表視圖數據源方法。 –

回答

0

因爲completion塊的工作是當網絡調用完成向你彙報。 HTTPHelper正在向服務器發出呼叫,這可能需要相當長的時間。它不會阻止您的程序執行,只是在該線路上等待:立即進入下一行,並呼叫print("Number of comments: \(self.comments.count)"),並且您得到0,因爲網絡呼叫尚未完成。然後,一段時間後,整個completion塊發生。

這就是所謂的異步功能,它通常會讓以前沒見過它的人絆倒,但最終會看到很多,所以值得一讀。

,你說:「當我關閉中添加tableView.reloadData()我得到一個錯誤index out of bounds for an empty array」,聽起來好像是配置表(cellForRowAtnumberOfRowsInSection)你UITableViewDataSource功能之一的事實,有一個錯誤它在某個地方。

+0

用我的表格視圖數據源方法更新了我的問題。 –

0

在您看到它們時不一定立即執行關閉。

在您的代碼中,封閉外部的print將在封閉內部的print之前執行。這是因爲getYelpComments就是所謂的「異步方法」。當您在等待Yelp服務器響應時,代碼不會坐在那裏無所事事。它在關閉後繼續執行代碼,打印計數爲0.

在Yelp響應之後,閉包得到執行。並且,計數爲3,被打印。

至於爲什麼把tableView.reloadData()導致它崩潰,你的表視圖數據源方法可能有問題。這很可能是1分。

編輯:

我覺得你寫

if section == 0 { 
    return super.tableView(tableView, numberOfRowsInSection: section) 

事實是怪異。我不知道爲什麼你想返回super實現,如果該部分是0.您的表視圖是否有多個部分?如果沒有,你應該刪除支票。如果是,則正確返回第一部分的值。

+0

用我的表格視圖數據源方法更新了我的問題。 –

+0

@ A.Jam見編輯答案。 – Sweeper

+0

第一部分是由靜態單元組成,這就是爲什麼我叫超級。第二部分的目的是讓動態單元格的評論將成爲。 –

相關問題