我的 Array 的 IndexPath 有问题吗?迅速 4 火力基地

Posted

技术标签:

【中文标题】我的 Array 的 IndexPath 有问题吗?迅速 4 火力基地【英文标题】:Something wrong with my Array's IndexPath? swift 4 Firebase 【发布时间】:2018-01-11 13:22:13 【问题描述】:

我不确定如何正确描述我的问题,但这是出了什么问题。

所以我有一个 TableView 填充了用户上传的posts,但我知道我想让我的用户能够评论彼此的帖子,当他们点击一个帖子时,他们会看到一个新的 ViewController,其中包含仅来自他们点击的帖子的数据。我已经做到了,所以这不是问题。但问题是,当他们单击 indexPath 时,它总是被单击的索引相同。例如,如果有 3 个帖子,名称为 test 1test 2test 3,那么他们点击的帖子始终是最新发布的帖子,因此在这种情况下,它始终是 test 3,即呈现。那么新的 viewController 是如何呈现的呢?所有posts 都通过FirebaseDatabase 生成的自动生成ID 上传和存储。

所以我使用此代码获取 AutoGenerated Id 并将其传递给全局变量并将其传递给 DetailViewController:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    let post = posts[indexPath.row]
    performSegue(withIdentifier: "CommentSegue", sender: post)

    Database.database().reference().child("posts").observe( .value)  (snapshot) in
        for child in snapshot.children 
            let snap = child as! DataSnapshot
            let key = snap.key
            postsKey = key
        
    


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 

    if segue.identifier == "CommentSegue"
        let commentVC = segue.destination as! CommentViewController
        commentVC.post = (sender as? NSDictionary?)!
    

我正在使用这种方法来删除帖子,它工作得很好,但这只是不是,所以我尝试发送数据的方式可能有问题,或者我附加的帖子是错误的到帖子数组的方式。

在 CommentViewController 中看起来像这样:

import UIKit
import FirebaseDatabase
import FirebaseStorage
import FirebaseAuth
import FirebaseCore
import Firebase

class CommentViewController: UIViewController 

var post: NSDictionary?

//  var comments: [NSDictionary] = []


let postKey = postsKey
@IBOutlet weak var titeLabel: UILabel!




override func viewDidAppear(_ animated: Bool) 
    loadData()






func loadData() 
        print(postKey)
        Database.database().reference().child("posts").child(postKey).observeSingleEvent(of: .value)  (snapshot) in
            if let dict = snapshot.value as? [String: AnyObject] 
                self.titeLabel.text = dict["title"] as? String


        
    

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

首先,使用sender 可能会造成混淆;通常,发送者是导致事件的人,而不是正在传输的任意数据。

我会用这个来改进你的代码:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    performSegue(withIdentifier: "CommentSegue", sender: tableView)
    // ...


override func prepare(for segue: UIStoryboardSegue, sender: Any?) 

    if segue.identifier == "CommentSegue"
        guard let commentVC = segue.destination as? CommentViewController else  return 
        guard let tableView = sender as? UITableView else  return 
        guard let selectedRow = tableView.indexPathForSelectedRow?.row else  return 

        let post =  posts[selectedRow]
        print("Selected: \(post)")
        commentVC.post = post
    

现在,根据按下的行检查prepare(for:sender:) 中的post 是否具有正确的值(它应该)(观察打印语句的输出)

如果post一直正确,可能CommentViewController没有正确更新UI(可能只是第一次),所以检查viewDidLoad/viewDidAppear里面的功能。也许你也应该在这里发布它的代码。

更新

我认为您需要从CommentViewController 中提供的post 字典中获取帖子的数据库密钥,可能是这样的:

func loadData() 
    postKey = post["key"] // or something else, you'll need to fetch the data base key from the current dictionary
    Database.database().reference().child("posts").child(postKey).observeSingleEvent(of: .value)  (snapshot) in
        if let dict = snapshot.value as? [String: AnyObject] 
            self.titeLabel.text = dict["title"] as? String
    

【讨论】:

我也不确定你在用 postKey 做什么,但你提到你正在使用它作为你的DetailViewContoller 的全局变量。虽然我不喜欢使用全局变量,但您确实还需要检查竞争条件。您应该将 performSegue(...) 放在数据库调用闭包(完整句柄)内。目前,您的 segue 在您的数据库调用返回之前触发,而您将传递的信息存储到全局中,我认为 UI 是在处理数据库响应之前布局的。 @JacobBoyd 我已经更新了我的问题,现在在 CommentViewController 中显示了它的样子。 @AndreasOetjen 您的代码完美运行 postKey 现在它们是否正确索引但仍在 CommentViewController 中它仅显示 test 3 但在控制台中我正在打印 postKey 它正在打印正确的索引 那么,DetailViewController 中的 post 是做什么用的? postKeypostsKey 是什么?请参阅上面我修改过的分析器。 那么您应该将答案标记为“已回答”,以便将来向任何人展示这可以解决您的问题。 能否请您检查一下这个问题,我想您可以帮助我解决这个问题。谢谢。[***.com/questions/48241086/…

以上是关于我的 Array 的 IndexPath 有问题吗?迅速 4 火力基地的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 无法使用“IndexPath”类型的索引为“[Array<String>]”类型的值下标

我的 UICollectionView 的 IndexPath 错误

在 TableView 中查找 [indexpath.row] 值

为啥我的 tableview 没有滚动到请求的 indexPath?

数组,找到具有值的对象并获取其 indexPath

我如何使用 indexPath.Autorelease ?删除最后一个索引值