2017-04-21 38 views
0

我已經在ViewController類的開始處聲明瞭requestPostArray。我試圖從數據庫「Request Posts」填充requestPostArray,然後從requestPostArray填充tableView。但是,當我打印它的大小顯示爲0.任何幫助,將不勝感激。在關閉之外訪問一個變量Swift3

此外,下面的整個else語句在另一個閉包中。

else { 

      ref.child("Request Posts").observe(.value, with: { (snapshot) in 
       let count = Int(snapshot.childrenCount) 

       // Request Post database is empty 
       if count == 0 { 
        cell.nameLabel.text = "No requests so far." 
        cell.userNameLabel.isHidden = true 
        cell.numberOfRequestsLabel.isHidden = true 
       } 

       // Request Post data is populated 
       else { 

        var requestPostArray: [RequestPost]? = [] 
        self.ref.child("Request Posts").observe(.value, with: { (snapshot) in 
         if let result = snapshot.children.allObjects as? [FIRDataSnapshot] { 

          for child in result { 
           let post = RequestPost(snapshot: child) 
           requestPostArray?.append(post) 
          } 
         } 

         else { 
          print("No Result") 
         } 
        }) 


        print("RequestPostArray size = \(requestPostArray?.count ?? 90)") 

        cell.nameLabel.text = self.requestPostArray?[indexPath.row].name 
        cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name 
        cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name 
       } 
      }) 
     } 

回答

1

這是應該發生的情況,因爲觀察功能是異步的,而其餘代碼是同步的,此外,如果從requestPostArray?中刪除可選的解包,您將得到一個零異常,因爲異步任務需要時間才能執行,編譯器會在它之前執行snyc任務。 基本上你所要做的是以下

else { 

       ref.child("Request Posts").observe(.value, with: { (snapshot) in 
        let count = Int(snapshot.childrenCount) 

        // Request Post database is empty 
        if count == 0 { 
         cell.nameLabel.text = "No requests so far." 
         cell.userNameLabel.isHidden = true 
         cell.numberOfRequestsLabel.isHidden = true 
        } 

        // Request Post data is populated 
        else { 

         var requestPostArray: [RequestPost]? = [] 
         self.ref.child("Request Posts").observe(.value, with: { (snapshot) in 
          if let result = snapshot.children.allObjects as? [FIRDataSnapshot] { 

           for child in result { 
            let post = RequestPost(snapshot: child) 
            requestPostArray?.append(post) 
           } 
          } 

          else { 
           print("No Result") 
          } 
print("RequestPostArray size = \(requestPostArray?.count ?? 90)") 

         cell.nameLabel.text = self.requestPostArray?[indexPath.row].name 
         cell.userNameLabel.text = self.requestPostArray?[indexPath.row].name 
         cell.numberOfRequestsLabel.text = self.requestPostArray?[indexPath.row].name 
         }) 



        } 
       }) 
      } 

另一個建議考慮使用單,所以你可以得到你的對象的重用,你會不會在同一方法調用數據庫中的幾個時間像你現在做。

+0

謝謝Achref!我對Swift比較陌生,所以我不太確定單身是什麼。你能簡單地告訴我它是什麼嗎?或者指向我可以找到更多關於它的鏈接?謝謝 – pranavhgupta

+0

請看看這裏http://stackoverflow.com/a/43513805/4442592,我包括一個完整的例子,爲進一步的細節,我想請你讀這個真棒教程:https://www.raywenderlich。 com/86477/introduction-ios-design-patterns-in-swift-part-1 –

+0

我的回答有用嗎? –

3

observe塊是異步的。在您的requestPostArray?.append(post)行修改之前,您正在閱讀requestPostArray

沒有更多的上下文,很難知道你想如何在這個對象上填充值,但是如果你需要「請求帖子」,那麼你必須等到你已經能夠獲得它們。

+0

謝謝喬納!我做「請求職位」數據庫。我創建了一個名爲「RequestPost」的自定義類型對象,並且我想將數據庫中的所有子元素存儲到名爲requestPostArray的RequestPost數組中,其成員將填充表格單元格。 我到底該如何「等到你能夠獲得它們」。是否有一個特定的功能,只有在塊完成執行後纔會觸發? – pranavhgupta

+2

它看起來像你試圖在表視圖數據源的'cellForRowAtIndexPath'內進行異步查詢。這不會起作用,因爲'cellForRowAtIndexPath'需要立即結果,並且不會等待您的查詢運行。請考慮'FUITableViewDataSource'(https://github.com/firebase/FirebaseUI-iOS/tree/master/FirebaseDatabaseUI)是如何設計來解決這個問題的。 – Jonah