【问题标题】:Declaring variable inside function not updating outside swift在函数内部声明变量不会在 swift 外部更新
【发布时间】:2017-06-28 23:11:27
【问题描述】:

我有一个函数,它可以进入 firebase 数据库并提取我存储的项目数量。当我在函数本身中打印变量 postCount 时它返回三个,但是当我在其他任何地方打印它时它只有零。它似乎没有更新全局值。

import UIKit
import Firebase

class ViewController: UIViewController, iCarouselDataSource, iCarouselDelegate {
    var items: [Int] = []
    var postCount = 0
    @IBOutlet var carousel: iCarousel!

    func getData() {
        Database.database().reference().child("Posts").observeSingleEvent(of: .value, with: { (snapshot) in
            if let dict2 = snapshot.value as? [String: AnyObject] {
                self.postCount = dict2.count
            }

            //This prints 3
            print(self.postCount)
        })
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        print(self.postCount)
        for i in 0 ... 99 {
            items.append(i)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        getData()
        print(self.postCount)
        carousel.type = .cylinder
    }

    func numberOfItems(in carousel: iCarousel) -> Int {
        return postCount
    }

    func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
        var label: UILabel
        var itemView: UIImageView

        //reuse view if available, otherwise create a new view
        if let view = view as? UIImageView {
            itemView = view
            //get a reference to the label in the recycled view
            label = itemView.viewWithTag(1) as! UILabel
        } else {
            //don't do anything specific to the index within
            //this `if ... else` statement because the view will be
            //recycled and used with other index values later
            itemView = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 400))
            itemView.image = UIImage(named: "page.png")
            itemView.layer.borderWidth = 10
            itemView.contentMode = .center

            label = UILabel(frame: itemView.bounds)
            label.backgroundColor = .clear
            label.textAlignment = .center
            label.font = label.font.withSize(50)
            label.tag = 1
            itemView.addSubview(label)
        }

        //set item label
        //remember to always set any properties of your carousel item
        //views outside of the `if (view == nil) {...}` check otherwise
        //you'll get weird issues with carousel item content appearing
        //in the wrong place in the carousel
        label.text = "\(items[index])"

        return itemView
    }

    func carousel(_ carousel: iCarousel, valueFor option: iCarouselOption, withDefault value: CGFloat) -> CGFloat {
        if (option == .spacing) {
            return value * 1.1
        }
        return value
    }

}

【问题讨论】:

  • 您确定没有在“viewDidLoad”之前调用“awakeFromNib”吗?我不肯定,但它可能是 super.viewDidLoad() 的一部分。尝试将 super.viewDidLoad() 移动到 viewDidLoad() 的底部

标签: swift function methods global-variables


【解决方案1】:

我相信这是因为从 Firebase 检索数据是异步的。 getData() 被调用,然后您立即 print(self.postCount),即使 getData() 仍在从 Firebase 检索数据。

尝试将getData() 中的print(self.postCount) 更改为

print("Data Loaded and there are \(self.postCount) posts")

您应该在日志中看到 viewDidLoad() 中的 print(self.postCount) 在 getData() 中的 print 之前被调用。因此,当调用 viewDidLoad() 中的print(self.postCount) 时,postCount 仍然等于默认值 0,因为即使 print 在 getData() 之后在线,getValue() 还没有完成运行。

您可能希望在getData() 的闭包内调用需要使用更新后的postCount 的任何函数,以确保这些函数使用更新后的postCount。

例如:

func getData() {
    Database.database().reference().child("Posts").observeSingleEvent(of: .value, with: { (snapshot) in
        if let dict2 = snapshot.value as? [String: AnyObject] {
            self.postCount = dict2.count
        }

        print(self.postCount)

        //everything within this closure will have the updated value of postCount
        foo()
    })
}

func foo() {
    if self.postCount > 0 {
        print("Lots of posts!")
    }
    else {
        print("No posts :(")
    }
}

【讨论】:

    猜你喜欢
    • 2019-09-23
    • 2019-02-08
    • 2015-02-10
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多