ios - 为什么实例变量在闭包内具有不同的值?

标签 ios swift uitableview alamofire

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 数据。令我惊讶的是,尽管通过向其附加新的 YelpComment 对象来更新 comments 实例数组,但其 count 在内部和外部具有不同的值关闭。

这些注释应该显示在表格 View 中。更让我困惑的是,当我在闭包中添加 tableView.reloadData() 时,我得到一个 index out ofbounds for anempty array 错误,但是当我添加同一行代码:在闭包之外的 tableView.reloadData() 我没有收到任何错误,并且 comments.count 等于零。任何帮助将非常感激!

附注我不知道提及这一点是否会产生任何影响,但 data@escaping。我还使用 SwiftyJSON 和 Alamofire。

更新:

我的表格 View 数据源方法是:

   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
        }
    }

最佳答案

因为 completion 的工作block 是在网络调用完成时向您报告。 HTTPHelper正在调用服务器,这可能需要相当长的时间。它不会停止您的程序执行,而只是在那一行等待:它立即转到下一行,并调用 print("Number of comments: \(self.comments.count)") ,你得到 0,因为网络调用还没有完成。然后,过了一段时间,整个completion发生阻塞。

这称为异步函数,它通常会让以前没有见过它的人感到困惑,但您最终会看到很多它,因此值得一读。

事实上,您说“当我在闭包中添加 tableView.reloadData() 时,我收到 index out of bounds for an empty array 错误”,这听起来像是配置表的 UITableViewDataSource 函数之一( cellForRowAtnumberOfRowsInSection ) ,某处有错误。

关于ios - 为什么实例变量在闭包内具有不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45784250/

相关文章:

iphone - 在iPhone中使用3G来电的Pjsip在UDP中时没有音频

ios - 展开 Storyboard(退出)segue 是否可以取代父场景中对子委托(delegate)的需求?

ios - 视频,上传到S3存储桶,不在iOS应用程序中通过url播放

ios - 如何保存使用 UIImagePickerController 相机拍摄的照片以便稍后在应用程序中显示?

ios - 编辑模式下的 UITableViewCell 子类布局

ios - 在 UITableViewCell 中逐行显示字符串的动画

swift - 在单元格中正确使用回调

ios - 当上下文为 nil 时,Swift Temp CoreData 对象无法设置 ivars

ios - 如何使用效果音频单元?

ios - Firebase:何时快速调用 removeObserverWithHandle