2017-06-28 4 views
-1

Ich habe eine Funktion, wo es in Firebase-Datenbank geht und zieht die Menge der Artikel, die ich gespeichert habe. Es gibt drei zurück, wenn ich die Variable postCount in der Funktion selbst drucke, aber wenn ich sie irgendwo anders drucke, hat sie nur Null. Es scheint nicht den globalen Wert zu aktualisieren.Deklarieren Variable innerhalb Funktion nicht außerhalb außerhalb Swift

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 
    } 

} 
+0

Sind Sie sicher, dass die ‚awakeFromNib‘ nicht dazu aufgerufen, vor ‚viewDidLoad‘ ?, Ich bin nicht positiv, aber es könnte als Teil des super.viewDidLoad kommen() . Versuchen Sie, super.viewDidLoad() an den unteren Rand von viewDidLoad() zu verschieben – brw59

Antwort

0

Ich glaube, es ist, weil das Abrufen von Daten aus Firebase asynchron ist. getData() wird aufgerufen und dann sofort danach print(self.postCount), obwohl getData() immer noch die Daten von Firebase abruft.

Versuchen Sie, die print(self.postCount) innerhalb getData() zu

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

ändern und Sie sollten in Ihrem Protokoll sehen, dass die print(self.postCount) innerhalb viewDidLoad() vor dem print innerhalb getData() genannt wird. Wenn print(self.postCount) in viewDidLoad() aufgerufen wird, entspricht postCount daher immer noch dem Standardwert 0, da getValue() nicht ausgeführt wird, obwohl das print in der Zeile nach getData() ist.

Sie möchten wahrscheinlich alle Funktionen aufrufen, die das aktualisierte postCount innerhalb der Schließung in getData() verwenden müssen, damit Sie sicherstellen, dass diese Funktionen das aktualisierte postCount verwenden.

Zum Beispiel:

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 :(") 
    } 
} 
Verwandte Themen