2017-08-04 24 views
0

私はこの回答を数日間探しています。私は "Govind"と呼ばれる新しいviewcontrollerをインスタンス化しようとするたびに、私はSIGARBTエラーを取得します。私がSIGARBTエラーを取得する理由は、ビューコントローラでは変数を使用するためです。 yourVariable、ASIN、VariationImagesを使用して、データベース内の特定のノードを検索します。 yourVariable、ASIN、およびVariationImagesの値はfirebaseの値と同じに設定しても変更されません。 firebaseの値はゼロではありません。どこでもここに私のコードだSwiftグローバル変数が更新されていません

import UIKit 
    import Firebase 
    import FirebaseDatabase 
    var yourVariable = "" 
    var ProductsNumber = 100 
    var ASIN = "" 
    var Weblink = "" 
    var VariationImages = 5 

    class Initial: UIViewController, UICollectionViewDataSource, 
    UICollectionViewDelegate { 
    @IBOutlet weak var FrontPageCollectionView: UICollectionView! 

    var UIFrame = UIScreen.main.bounds 
    var ref: DatabaseReference! 
    var DatabaseHandle = nil as DatabaseHandle! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     ref = Database.database().reference() 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 3 
    } 

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     self.DatabaseHandle = ref.child("Frontpage").child(String(indexPath.row)).observe(.value, with: { (TheCategory) in 
      yourVariable = TheCategory.childSnapshot(forPath: "Category").value as! String 
      ASIN = TheCategory.childSnapshot(forPath: "ASIN").value as! String 
     self.DatabaseHandle = self.ref.child(TheCategory.childSnapshot(forPath: "Category").value as! String).child(TheCategory.childSnapshot(forPath: "ASIN").value as! String).child("VariationImages").observe(.value, with: { (NumberOfVariationImages) in 
      VariationImages = Int(NumberOfVariationImages.childrenCount) 
      }) 
     }) 
     CallGovind() 
    } 

    func CallGovind() { 
     let storyboard = UIStoryboard(name: "Main", bundle: nil) 
     let controller = storyboard.instantiateViewController(withIdentifier: "Govind") 
     controller.modalPresentationStyle = .popover 
     self.present(controller, animated: true, completion: nil) 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FrontpageCell", for: indexPath) as! myCell 
     self.DatabaseHandle = ref.child("Frontpage").child(String(indexPath.row)).child("Thumbnail").observe(.value, with: { (snapshot) in 
      cell.FrontpageImages.sd_setImage(with: URL(string: snapshot.value as! String), placeholderImage: #imageLiteral(resourceName: "Menu"), options: [.continueInBackground, .progressiveDownload]) 
     }) 
     cell.FrontpageImages.contentMode = .scaleAspectFill 
     cell.FrontpageImages.layer.cornerRadius = 5 
     cell.FrontpageImages.clipsToBounds = true 
     return cell 
    } 

    } 
    /* 
    // MARK: - Navigation 

    // In a storyboard-based application, you will often want to do a little preparation before navigation 
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     // Get the new view controller using segue.destinationViewController. 
     // Pass the selected object to the new view controller. 
    } 
    */ 

    } 

//Here's where the data goes into the second view controller 

    import UIKit 
    import Firebase 
    import FirebaseDatabase 


    class Testing: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 
    var ref: DatabaseReference! 
    var DatabaseHandle = nil as DatabaseHandle! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    //Populate view 
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cells", for: indexPath) as! myCell 
     self.DatabaseHandle = ref.child(yourVariable).child(ASIN).child("VariationImages").child(String(indexPath.row)).observe(.value, with: { (snapshot) in 
      cell.myImageViews.sd_setImage(with: URL(string: snapshot.value as! String), placeholderImage: #imageLiteral(resourceName: "Menu"), options: [.continueInBackground, .progressiveDownload]) 


      }) 
     return cell 
} 

DataBaseHandleは、ある変数が

+0

クラッシュが発生するコードを表示してください。 – Paulw11

+0

私は投稿を編集し、あなたが要求したコードを追加しました。@ Paulw11に返信ありがとうございます –

+0

Govindのコードを投稿できますか?これがクラッシュしているので、投稿する必要があります。 – ryantxr

答えて

1

を更新していないので、それが完了ハンドラがある前に、ほとんどの機能CallGovind()のあなたの呼び出しを実行なっている空の文字列であるため、エラーを生成します完了しました。これは、変数が設定されているの前に、他のView Controllerがと呼ばれることを意味します。

... .observe(.value, with: { (TheCategory) in 
    // Code in here will get executed asynchronously 
    // and likely will get called later 
    // Since you set variables in here, and they 
    // are not set by the time you call the other 
    // view controller. 
} 

CallGovind() // gets called BEFORE above code 

可能な解決策の1つは、完了ブロックの完了後にもう一方のビューコントローラが呼び出されるようにすることです。 ryantxr AS

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
    self.DatabaseHandle = ref.child("Frontpage").child(String(indexPath.row)).observe(.value, with: { (TheCategory) in 
     yourVariable = TheCategory.childSnapshot(forPath: "Category").value as! String 
     ASIN = TheCategory.childSnapshot(forPath: "ASIN").value as! String 
     self.DatabaseHandle = self.ref.child(TheCategory.childSnapshot(forPath: "Category").value as! String).child(TheCategory.childSnapshot(forPath: "ASIN").value as! String).child("VariationImages").observe(.value, with: { (NumberOfVariationImages) in 
      VariationImages = Int(NumberOfVariationImages.childrenCount) 
      // Call other controller here so that the variables 
      // are set 
      DispatchQueue.main.async { 
       CallGovind() 
      } 
     }) 
    }) 

} 
+1

感謝します。@ryantxrコードが完璧に機能しました。この問題があったことをありがとうございました。どうもありがとうございます!!! –

+0

コントローラ間でデータをやりとりする別の方法を検討することをお勧めします。 [legendary-potato](https://github.com/ryantxr/legendary-potato)をご覧ください。 – ryantxr

+0

ありがとうございます@ryantxr、私は本当にすべての助け、私の最初の時間Stackoverflowを使用して、私の心の底から感謝し、あなたはコミュニティの素晴らしい感覚を表示します。もう一度ありがとうございました –

0

は、すべてのクラスの中で変数を共有することも良い方法をクロージャ内callGovindを明記し、シングルトンです。

は、私の知識あたりとして、あなたは別々のシングルトンファイルを作成するように、この型の変数を管理するためにシングルトンクラスを作成する必要が

import Foundation 
/** 
* Created by Jaydeep on 13-Feb-17. 
*/ 

public class Singleton 
{ 
    var yourVariable : String = "" 
    static let shared = Singleton() 
    private init() 
    { 
    } 
} 

あなたはどこでも、常にシングルトンクラスのオブジェクトにアクセスすることができます

Singleton.shared.yourVariable = "xyz" 

使い方あなたは最後に更新された値を取得します。

+0

ありがとう、私はSingleTonクラスを見たことはありませんが、私が持っているので、それはうまくいくようです。ご協力いただきありがとうございます! @JaydeepVyas –

+0

この変数は "オープンクラス"に更新されないのはなぜですか? –

関連する問題