声明变量内部函数不在swift外部更新

时间:2017-06-28 23:11:28

标签: swift function methods global-variables

我有一个函数,它进入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
    }

}

1 个答案:

答案 0 :(得分:0)

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

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

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

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

您可能希望调用需要在getData()中的闭包内使用更新的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 :(") } }

例如:

var str = "alice-blue, antique-white, aqua";
var arr = str.split(', ');
for(var i=0; i< arr.length;i++){
   arr[i] = "'"+arr[i]+"'";
}
var resultStr = arr.join(", ");