无法访问超出功能的结构,超出范围

时间:2019-11-13 00:16:52

标签: swift

已编辑以编写整个代码。 我要解决的问题是,一旦我从Firebase获得数据,它就会一遍又一遍地显示相同的数据(数组的大小,在这种情况下为0、1、2)。正在正确检索数据。

enter image description here

在本地变量上更新数组时,似乎无法正确填充数组,因此在表视图中显示帖子时可以使用它。这是代码:

import UIKit
import Firebase
import FirebaseAuth
import Foundation

class StylerSalonHomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var tableView:UITableView!
    var posts = [Post]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView = UITableView(frame: view.bounds, style: .plain)

        let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
        tableView.register(cellNib, forCellReuseIdentifier: "postCell")

        view.addSubview(tableView)

        var layoutGuide:UILayoutGuide

        if #available(iOS 11.0, *){
            layoutGuide = view.safeAreaLayoutGuide
        }

        layoutGuide = view.safeAreaLayoutGuide

        tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
        tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
        tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true

        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()

        observe()

        tableView.reloadData()

    }


    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return posts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
        cell.set(post: posts[indexPath.row])
        return cell
    }

    internal func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
             return 180
     }



    @IBAction func handleLogout(_ target: UIBarButtonItem) {
        try! Auth.auth().signOut()
        self.dismiss(animated: false, completion: nil)
    }


    func observe() {
        let postsRef = Database.database().reference(withPath: "post")

                postsRef.observe(.value, with: { snapshot in
                    var tempPosts = [Post]()

                    for child in snapshot.children {
                        if let childSnapshot = child as? DataSnapshot,
                            let data = childSnapshot.value as? [String:Any],
                            let first_name = data["Author"] as? String,
                            let postTitle = data["title"] as? String,
                            let postDescription = data["description"] as? String,
                            let postUrl = data["postUrl"] as? String,
                            let postAddress = data["Address"] as? String,
                            let url = URL(string:postUrl)
                        {
                            let post = Post(author: first_name, postTitle: postTitle, postDescription: postDescription, postUrl: url, postAddress: postAddress)
                            tempPosts.append(post)

                        }
                    }

                    self.posts = tempPosts

                    // HERE IT WORKS
                    print(self.posts[0].postTitle , " 0")
                    print(self.posts[1].postTitle , " 1")

                    self.tableView.reloadData()
                })
        // HERE IT DOESN'T WORK
        print(self.posts[0].postTitle , " 0")
    }


    func getDateFromTimeStamp(timestamp : Double) -> String {
        let date = Date(timeIntervalSince1970: timestamp)
        let dateFormatter = DateFormatter()
        dateFormatter.timeZone = TimeZone(abbreviation: "GMT") //Set timezone that you want
        dateFormatter.locale = NSLocale.current
        dateFormatter.dateFormat = "HH:mm" //Specify your format that you want
        let strDate = dateFormatter.string(from: date)

        return strDate
    }

}

我必须访问我的数据并将其存储到var posts = [Post]()中的函数是observe(),但是如果您注意到那里的注释,则无法在该函数之外调用该数组,那可能是问题?当我这样做时,它说:Thread 1: Fatal error: Index out of range

我认为错误是访问postsRef.observe(.value, with: { snapshot in之外的数据

1 个答案:

答案 0 :(得分:0)

我无法完全确定自己没有看到所有代码,但是我认为这是时间问题。

在运行observe()之前,数据库上将没有任何观察者,然后它将不会填充updatePosts.posts数组中的任何数据,直到(1)触发了数据库更改快照,然后(2)关闭操作完成了快照的处理。

您在哪里打电话给observe()?是在viewDidLoad运行并尝试打印出数组内容之前?并且您有信心在viewDidLoad运行时将接收并处理快照吗?否则,在viewDidLoad中,您将尝试为posts数组中尚不存在的项目建立索引,这就是为什么会出现index out of range错误的原因。

您要在viewDidLoad中实现什么,这意味着您需要访问posts数组,因为可能有另一种方法可以避免此问题?