Ios Swift变量赋值后仍为0?

Ios Swift变量赋值后仍为0?,ios,swift,firebase,Ios,Swift,Firebase,在我的viewDidLoad中,我打印出一个函数的结果 override func viewDidLoad() { super.viewDidLoad() print("top count = \(getCurrentOrderNum())") } 该函数计算值如下所示 func getCurrentOrderNum() -> Int{ var orderNum = 0 ref = Firebase(url: "urlhiddenforprivacy")

在我的viewDidLoad中,我打印出一个函数的结果

override func viewDidLoad() {
    super.viewDidLoad()
    print("top count = \(getCurrentOrderNum())")
}
该函数计算值如下所示

func getCurrentOrderNum() -> Int{
    var orderNum = 0
    ref = Firebase(url: "urlhiddenforprivacy")
    ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
        let count = snapshot.childrenCount
            orderNum = Int(count)
    })
    return orderNum
}
但它仍然打印0?我试图将var orderNum:Int=Int放在代码的顶部,而不是放在getCurrentOrderNum函数中,但没有成功。我知道它在我的ref.observe函数中得到了正确的值,因为当我运行这个函数时。。。它打印出正确的值

    ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
        let count = snapshot.childrenCount
            orderNum = Int(count)
            print(orderNum) //*****THIS PRINTS THE RIGHT VALUE****
    })
    return orderNum
}
在异步块实际运行之前,从方法getCurrentOrderNum返回orderNum。因此在返回时,orderNum仍然是0,即您设置的初始值。该块稍后完成

您最好的选择可能是将方法更改为:

func getCurrentOrderNum(callback:Int->()) {
    var orderNum = 0
    ref = Firebase(url: "urlhiddenforprivacy")
    ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
        let count = snapshot.childrenCount
        orderNum = Int(count)
        callback(orderNum)
    })
}
然后你会这样称呼它:

override func viewDidLoad() {
    super.viewDidLoad()
    getCurrentOrderNum { orderNum in print(orderNum) }
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int)->Int { 
    return getCurrentOrderNum() 
}
这将更改getCurrentOrderNum方法,使其在完成检索正确值后回调闭包

更新:根据下面的评论,我们的目标是这样做:

override func viewDidLoad() {
    super.viewDidLoad()
    getCurrentOrderNum { orderNum in print(orderNum) }
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int)->Int { 
    return getCurrentOrderNum() 
}
以下是一种异步方法:

class YourViewController : UIViewController, UITableViewDataSource {

    private var orderNumber:Int = 0
    private IBOutlet var tableView:UITableView!

    func getCurrentOrderNum(callback:Int->()) {
        ref = Firebase(url: "urlhiddenforprivacy")
        ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
            let count = snapshot.childrenCount
            callback(Int(count))
        })
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        getCurrentOrderNum {
            orderNum in
            //This code runs after Firebase returns the value over the network
            self.orderNumber = orderNum  // Set our orderNumber to what came back from the request for current order number
            self.tableView.reloadData()  // Now reload the tableView so it updates with the correct number of rows
        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {    
        return self.orderNumber // When the view first loads, this will be 0 and the table will show nothing.  After the request to Firebase returns the value, this will be set to the right number, the table view will be reloaded, and it will call this method again to get the updated number of rows to display.
    }
}
在异步块实际运行之前,从方法getCurrentOrderNum返回orderNum。因此在返回时,orderNum仍然是0,即您设置的初始值。该块稍后完成

您最好的选择可能是将方法更改为:

func getCurrentOrderNum(callback:Int->()) {
    var orderNum = 0
    ref = Firebase(url: "urlhiddenforprivacy")
    ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
        let count = snapshot.childrenCount
        orderNum = Int(count)
        callback(orderNum)
    })
}
然后你会这样称呼它:

override func viewDidLoad() {
    super.viewDidLoad()
    getCurrentOrderNum { orderNum in print(orderNum) }
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int)->Int { 
    return getCurrentOrderNum() 
}
这将更改getCurrentOrderNum方法,使其在完成检索正确值后回调闭包

更新:根据下面的评论,我们的目标是这样做:

override func viewDidLoad() {
    super.viewDidLoad()
    getCurrentOrderNum { orderNum in print(orderNum) }
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int)->Int { 
    return getCurrentOrderNum() 
}
以下是一种异步方法:

class YourViewController : UIViewController, UITableViewDataSource {

    private var orderNumber:Int = 0
    private IBOutlet var tableView:UITableView!

    func getCurrentOrderNum(callback:Int->()) {
        ref = Firebase(url: "urlhiddenforprivacy")
        ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
            let count = snapshot.childrenCount
            callback(Int(count))
        })
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        getCurrentOrderNum {
            orderNum in
            //This code runs after Firebase returns the value over the network
            self.orderNumber = orderNum  // Set our orderNumber to what came back from the request for current order number
            self.tableView.reloadData()  // Now reload the tableView so it updates with the correct number of rows
        }
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {    
        return self.orderNumber // When the view first loads, this will be 0 and the table will show nothing.  After the request to Firebase returns the value, this will be set to the right number, the table view will be reloaded, and it will call this method again to get the updated number of rows to display.
    }
}

一般来说,使用Firebase返回函数结果可能很棘手——它采用异步进程并将其压缩为同步进程。正如丹尼尔斯的好答案所示,这是可以做到的,但也有其他选择。通过查看问题中的代码,可能有几个重要的Firebase概念被忽略了

我想介绍一个利用Firebase强大功能的超级简单异步解决方案

以下是一些概念性的东西:

定义变量以跟踪订单号-

var currentOrderNumber = Int
火基结构

orders
  order_id_00
    order_num: 12345
  order_id_01
    order_num: 12346
people
  person_id_0
     name: "Bill"
  person_id_1
     name: "Larry"
在viewDidLoad的orders节点上设置一个观察者,以便在添加新订单时通知应用程序。这将在订单写入节点时发生,以便所有客户端都知道当前订单号:

ref.queryOnOrdersNode.childAdded { snapshot in

  if let orderNumber = snapshot.value["order_num"] as? Int {
     currentOrderNumber = orderNumber
  }

}
从那时起,无论何时打印currentOrderNumber,它都将包含实际的currentOrderNumber

这是相当酷的,因为你让Firebase做繁重的工作;Firebase不会反复轮询Firebase以获取当前订单号,而是在更改时告诉您的应用程序当前订单号

您可以在此基础上展开以填充tableView,并通过添加内容使其保持更新

火基结构

orders
  order_id_00
    order_num: 12345
  order_id_01
    order_num: 12346
people
  person_id_0
     name: "Bill"
  person_id_1
     name: "Larry"
以及填充数组并添加观察者以供将来添加的代码:

var namesArray = [String]

peopleNode.observeEventType(.ChildAdded) { snapshot in

    if let name = child.value["name"] as? String {
       namesArray.append(name)
       self.tableView.reloadData
    }  
}
以及tableView委托方法

func tableView(tableView: UITableView, numberOfRowsInSection section: Int)->Int { 
    return peopleArray.count
}
再一次,这让Firebase完成了繁重的工作;您不必轮询数据,因为Firebase会告诉您的应用程序,并且tableView会自动更新,当一个新的人员添加到“人员”节点时

您会注意到,代码非常简短和紧凑,因为您让Firebase完成了大部分工作,以使您的变量保持更新,并用新数据填充表


这段代码中有拼写错误,因为它是概念性的

一般来说,使用Firebase返回函数结果可能很棘手-它采用异步进程并将其压缩为同步进程。正如丹尼尔斯的好答案所示,这是可以做到的,但也有其他选择。通过查看问题中的代码,可能有几个重要的Firebase概念被忽略了

我想介绍一个利用Firebase强大功能的超级简单异步解决方案

以下是一些概念性的东西:

定义变量以跟踪订单号-

var currentOrderNumber = Int
火基结构

orders
  order_id_00
    order_num: 12345
  order_id_01
    order_num: 12346
people
  person_id_0
     name: "Bill"
  person_id_1
     name: "Larry"
在viewDidLoad的orders节点上设置一个观察者,以便在添加新订单时通知应用程序。这将在订单写入节点时发生,以便所有客户端都知道当前订单号:

ref.queryOnOrdersNode.childAdded { snapshot in

  if let orderNumber = snapshot.value["order_num"] as? Int {
     currentOrderNumber = orderNumber
  }

}
从那时起,无论何时打印currentOrderNumber,它都将包含实际的currentOrderNumber

这是相当酷的,因为你让Firebase做繁重的工作;Firebase不会反复轮询Firebase以获取当前订单号,而是在更改时告诉您的应用程序当前订单号

您可以在此基础上展开以填充tableView,并通过添加内容使其保持更新

火基结构

orders
  order_id_00
    order_num: 12345
  order_id_01
    order_num: 12346
people
  person_id_0
     name: "Bill"
  person_id_1
     name: "Larry"
以及填充数组并添加观察者以供将来添加的代码:

var namesArray = [String]

peopleNode.observeEventType(.ChildAdded) { snapshot in

    if let name = child.value["name"] as? String {
       namesArray.append(name)
       self.tableView.reloadData
    }  
}
以及tableView委托方法

func tableView(tableView: UITableView, numberOfRowsInSection section: Int)->Int { 
    return peopleArray.count
}
再一次,这让Firebase完成了繁重的工作;Firebase告诉您的应用程序和tabl,您不必像在人员节点中添加新人员那样进行数据轮询 eView会自动更新

您会注意到,代码非常简短和紧凑,因为您让Firebase完成了大部分工作,以使您的变量保持更新,并用新数据填充表


这段代码中有输入错误,因为它是概念性的

observeSingleEventOfType是一个异步操作吗?我想是。。。那就是你的问题了。Idk老实说,这意味着什么,但如果它是一个异步操作,我该如何修复它呢?就像Eric D说的:observeSingleEventOfType是一个块,似乎是异步的。所以在你的街区结束之前,你会回来。这就是为什么您总是打印0I试图在它完成之前返回它,但该块是一个空函数,因此它无法返回任何内容:/Daniels answer将起作用,但我认为您的代码可能过于复杂。请问订单号是用来做什么的?什么时候需要?我的问题是,当你的应用程序启动时,你可以观察订单号以获得初始值。然后,每当任何客户端更新它时,都会自动通知您的应用程序发生了更改;订单号将始终是准确的,而不是轮询。此外,您可能希望根据childCount更改订单号,因为有更好的解决方案-一旦我们有更多信息,可以在回答中解决。observeSingleEventOfType是否可能是一个异步操作?我想是。。。那就是你的问题了。Idk老实说,这意味着什么,但如果它是一个异步操作,我该如何修复它呢?就像Eric D说的:observeSingleEventOfType是一个块,似乎是异步的。所以在你的街区结束之前,你会回来。这就是为什么您总是打印0I试图在它完成之前返回它,但该块是一个空函数,因此它无法返回任何内容:/Daniels answer将起作用,但我认为您的代码可能过于复杂。请问订单号是用来做什么的?什么时候需要?我的问题是,当你的应用程序启动时,你可以观察订单号以获得初始值。然后,每当任何客户端更新它时,都会自动通知您的应用程序发生了更改;订单号将始终是准确的,而不是轮询。此外,您可能希望根据childCount更改订单号,因为有更好的解决方案-一旦我们有更多信息,可以在回答中解决。我从未使用过类似的方法?如何将变量指定给函数的结果?类似于-orderNum=getCurrentOrderNum这是我想要做的func tableViewtableView:UITableView,numberOfRowsInSection:Int->Int{return getCurrentOrderNum}@LukePatterson,因为在您想要将getCurrentOrderNum分配给变量的时候结果不可用,您必须将依赖于获得该结果的所有代码移动到回调块中,如下所示:getCurrentOrderNum{orderNum in let nextOrder=orderNum+1//使用orderNum执行其他操作}另一个选项是让整个应用程序在您想要获取orderNum的位置暂停,直到从Firebase检索到orderNum,然后继续赋值。但这是一种糟糕的用户体验和糟糕的做法。@LukePatterson关于tableView数据源方法,请记住,在tableView询问行数的那一刻,您的应用程序还不知道应该有多少行。要从FireBase获取orderNum,is需要通过网络发送请求并获得响应。这可能需要100毫秒或几秒钟的等待,谁知道呢?但是表视图需要立即响应。我会用一种方法来更新我的答案,我从来没有用过这样的方法?如何将变量指定给函数的结果?类似于-orderNum=getCurrentOrderNum这是我想要做的func tableViewtableView:UITableView,numberOfRowsInSection:Int->Int{return getCurrentOrderNum}@LukePatterson,因为在您想要将getCurrentOrderNum分配给变量的时候结果不可用,您必须将依赖于获得该结果的所有代码移动到回调块中,如下所示:getCurrentOrderNum{orderNum in let nextOrder=orderNum+1//使用orderNum执行其他操作}另一个选项是让整个应用程序在您想要获取orderNum的位置暂停,直到从Firebase检索到orderNum,然后继续赋值。但这是一种糟糕的用户体验和糟糕的做法。@LukePatterson关于tableView数据源方法,请记住,在tableView询问行数的那一刻,您的应用程序还不知道应该有多少行。要从FireBase获取orderNum,is需要通过网络发送请求并获得响应。这可能需要100毫秒或几秒钟的等待,谁知道呢?但是表视图需要立即响应。我将用w的方法更新我的答案 你想做什么