如何在单例类中共享变量

时间:2015-05-08 04:05:32

标签: swift parsing singleton

我正在尝试创建一个用于在Parse中存储和检索数据的公共类。我使ParseProcessing类成为单例类。从我的主View Controller中加载数据并将其存储到ParseProcessing中的字典中。我这样做是通过创建ParseProcessing类的共享实例。从另一个视图控制器我尝试从字典中访问数据。我假设因为ParseProcessing是一个单例类,我有一个字典的副本。这似乎不正确。我应该如何在ParseProcessing中声明变量以便它们被共享?代码如下所示:

import UIKit

var gSep = ","

class QwikFileViewController: UIViewController {

var loadData = ParseProcessing.sharedInstance

override func viewDidLoad() {
    super.viewDidLoad()

    // load data from Parse
    loadData.loadCategorySubcategoryData()
    loadData.loadRecordsFromParse()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}

ParseProcessing Singleton Class

import UIKit
import Parse

class ParseProcessing: Parse  {


var dictMenuList = [String:String]()
var noteTitle = [String]()
var notes = [String]()
var thumbnailFiles = [PFFile]()
var objectIds = [String]()
var noteImage = UIImage()


class var sharedInstance:ParseProcessing {

    struct singleton {

        static let instance:ParseProcessing = ParseProcessing()
    }

    return singleton.instance
}
// Load Category/Subcategory data from Parse Data Base

func loadRecordsFromParse () -> Bool{
    var tmpFile = [PFFile]()
    var loadComplete = false
    var query = PFQuery(className:"Record")


    query.findObjectsInBackgroundWithBlock {
        (objects, error) -> Void in
        if error == nil {
            // The find succeeded.
            println("Successfully retrieved \(objects!.count) items.")
            for object in objects! {
                self.noteTitle.append(object["title"] as! String)
                self.notes.append(object["notes"] as! String)
                self.thumbnailFiles.append(object["thumbnail"] as! PFFile)
                       self.objectIds.append(String(stringInterpolationSegment: object.objectId))
            }
        } else {
            println("\(error)")
       }
        loadComplete = true
    }


    return loadComplete
}

// Load Category/Subcategory data from Parse Data Base

func loadCategorySubcategoryData () // -> Dictionary <String,String> 
    {
    var success : Bool = false
    var d : Dictionary <String,String> = ["":""]
    var menu = PFQuery(className: "Classification")
    println("ParseProcessing: loadCategory...")
    menu.findObjectsInBackgroundWithBlock {
        (objects, error) -> Void in
        if error == nil {

            var category = ""
            var subcategory = ""
            for object in objects! {

                category = object["category"] as! String
                println("ParseProcessing: category = \(category)")

                subcategory = object["subcategory"] as! String
                println("ParseProcessing: subcategory = \(subcategory)")
                d[category] = subcategory
            }
            success = true
            self.dictMenuList = d
            return
        } else {
            println("ParseProcessing: error = \(error)")
            success = false
        }

    }
   return
}

}

另一个用于检查数据的View Controller

import UIKit

class TestViewController: UIViewController {

var dictMenuList = [String:String]()
var loadData  = ParseProcessing.sharedInstance

override func viewDidLoad() {
    super.viewDidLoad()
    dictMenuList = loadData.dictMenuList
    println("dictMenuList: \(dictMenuList)")
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

}

1 个答案:

答案 0 :(得分:1)

问题是findObjectsInBackgroundWithBlock是异步方法(即它立即返回,但稍后在查询完成时调用闭包)。因此,您无法在loadComplete中返回loadRecordsFromParse。这个后台请求几乎肯定不会在loadRecordsFromParse返回时完成。

相反,您可能希望采用completionHandler模式。例如,此示例loadRecords不会立即返回任何内容,而是在请求完成时调用completionHandler

func loadRecords(completionHandler:([SomeObject]?, NSError?) -> ()) {
    let query = PFQuery(className: "SomeClass")

    query.findObjectsInBackgroundWithBlock { objects, error in
        // build some model object
        completionHandler(objectArray, error)
    }
}

你会这样称呼它:

loadData.loadRecords() { objects, error in
    // use `objects` (and make sure `error` is `nil`) here
}

// but do not use those variables here, as the above closure probably has not run yet!
坦率地说,我倾向于完全摆脱你的单身人士的那些属性。当您处理异步代码时,让异步更新的公共属性将成为一个令人心痛的根源。你可以这样做,但这不是我的第一选择。

例如,当出现TestViewController时,您不能假设与dictMenuList关联的异步提取尚未完成。我看一下这个并想知道TestViewController启动提取本身然后在完成处理程序中使用dictMenuList是否有意义。这将是最简单的。

如果必须从一个视图控制器启动异步请求,然后在异步请求完成时通知另一个视图控制器,那么您可能必须使用其他一些模式,例如通知(例如使用NSNotificationCenter ,并在完成各种请求时发出单例发布通知,然后需要通知此事实的任何视图控制器都可以将自己添加为该通知的观察者。)