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
。我还在使用SwiftyJSON
和Alamofire
。
更新:
我的表视图数据源方法是:
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 :(得分:0)
因为completion
块的作业是在网络呼叫完成时向您报告。 HTTPHelper
正在调用服务器,这可能需要相当长的时间。它不会阻止你的程序执行,只是在那一行等待:它立即进入下一行,然后调用print("Number of comments: \(self.comments.count)")
,你得到0,因为网络调用还没有完成。然后,一段时间后,整个completion
阻止发生。
这被称为异步功能,它通常会绊倒之前没有看过它的人,但最终会看到很多,所以值得一读。
你说“当我在闭包中添加tableView.reloadData()时出现index out of bounds for an empty array
错误”,这听起来像是一个配置表(cellForRowAt
的UITableViewDataSource函数, numberOfRowsInSection
),在某处出现错误。
答案 1 :(得分:0)
闭包不一定在您看到它们时立即执行。
在你的代码中,闭包之外的print
将在闭包内的print
之前执行。这是因为getYelpComments
是所谓的“异步方法”。当您在等待Yelp服务器响应时,代码不会只是坐在那里什么都不做。它在关闭后继续执行代码,打印计数为0。
在Yelp响应之后,闭包被执行。并且计数为3,打印出来。
至于为什么把tableView.reloadData()
导致它崩溃,你的表视图数据源方法可能有问题。它很可能是1分之一。
编辑:
我认为你写的事实
if section == 0 {
return super.tableView(tableView, numberOfRowsInSection: section)
很奇怪。如果部分为0,我不知道为什么要返回super
实现。您的表视图是否有多个部分?如果没有,您应该删除支票。如果是,则正确返回第一部分的值。