繁体   English   中英

Swift全局变量未更新

[英]Swift global Variables Not Updating

我一直在寻找这个答案好几天了。 每当我尝试实例化名为“ Govind”的新视图控制器时,都会收到SIGARBT错误。 我收到SIGARBT错误的原因是因为在名为I的视图控制器中使用了变量。 yourVariable,ASIN,VariationImages,以查找数据库中的特定节点。 当我将它们设置为与firebase中的值相等时,yourVariable,ASIN和VariationImages的值不会更改。 firebase中的值不是nil。 这是我的代码

 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到处都会产生错误,因为它是一个空字符串,因为变量尚未更新

最有可能在完成处理程序完成之前执行对函数CallGovind()调用。 这意味着设置变量之前,将调用另一个视图控制器。

... .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

一种可能的解决方案是确保在完成完成块之后调用另一个视图控制器。

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()
            }
        })
    })

}

AS ryantxr在闭包内部声明了callGovind,在所有类之间共享变量的好方法是singleTon。

据我所知,您必须创建SingleTon类来管理此类型变量,例如创建单独的singleton文件

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"

您可以在任何地方访问singleTon类对象,并且始终可以获取最新的更新值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM