2016-04-21 35 views
1

在我viewDidLoad中()打印出一個函數Swift變量在賦值後仍然爲0?

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 
} 
+2

是'萬一observeSingleEventOfType'異步操作?那我想是...那是你的問題。 – Moritz

+0

Idk坦白地說,但如果它是異步操作,我該如何解決它?像Eric D說的 –

+1

說:'observeSingleEventOfType'是一個塊,似乎是異步的。所以在你的街區結束之前,你會回來。這就是爲什麼你總是打印0 – Mindhavok

回答

6

你是從方法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) } 
} 

這改變了getCurrentOrderNum()方法來一次回調至關閉它已完成檢索正確的值。

UPDATE:基於下面的評論,我們的目標是做這樣的事情:

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. 
    } 
} 
+0

我從來沒有用過這樣的東西?如何爲函數的結果分配一個變量?這樣的事情 - ORDERNUM = getCurrentOrderNum() –

+0

這就是我想要做的 FUNC的tableView(的tableView:UITableView的,numberOfRowsInSection段中:int) - >詮釋{ 回報getCurrentOrderNum() } –

+0

@LukePatterson由於結果是不如果您想要將getCurrentOrderNum()分配給變量,您必須將所有取決於該結果的代碼移動到回調塊中,如下所示: getCurrentOrderNum { orderNum in let nextOrder = orderNum + 1 //用orderNum做其他東西,現在我們擁有它 } 另一種選擇是讓你的整個應用程序ju在您希望獲取orderNum的點暫停,直到從Firebase檢索到它,然後繼續分配值。但這是一種糟糕的用戶體驗和糟糕的做法。 –

0

一般返回函數結果可能會非常棘手 - 它正在採取異步處理並將其壓縮到同步處理中。儘管可以完成(如丹尼爾斯的良好答案所示),但還有其他選擇。通過查看問題中的代碼,可能會有一些重要的Firebase概念可能被忽略。

我想介紹一個利用Firebase功能的超級簡單的異步解決方案。

下面是一些概念性的東西:

定義一個變種,以保持順序號的軌跡 -

var currentOrderNumber = Int 

火力地堡結構

orders 
    order_id_00 
    order_num: 12345 
    order_id_01 
    order_num: 12346 

在viewDidLoad中設立觀察員訂單節點上在添加新訂單時通知應用程序。這將產生一個訂單被寫入節點,以便隨後的任意時間所有的客戶都知道目前的訂單號碼是什麼:

ref.queryOnOrdersNode.childAdded { snapshot in 

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

} 

,從那時起,每當currentOrderNumber打印,它將包含實際currentOrderNumber。

這是非常酷的,你讓Firebase做繁重的工作; Firebase會反覆輪詢Firebase以獲取currentOrderNumbers,它會告訴您的應用當前訂單號碼在更改時的內容。

你可以擴展這個來填充一個tableView,並保持其更新。

火力結構

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爲您完成了大部分工作,讓您的變量保持最新狀態,並使用新數據填充表格。

(有這碼輸入錯誤,因爲它是概念上的)