如何在单例中共享变量 class

How do I share variables inside a singleton class

我正在尝试创建一个通用 class 用于在 Parse 中存储和检索数据。我将 ParseProcessing class 设为单例 class。我从我的主视图控制器加载数据并将其存储到 ParseProcessing 中的字典中。我通过创建 ParseProcessing class 的共享实例来做到这一点。我尝试从另一个视图控制器访问字典中的数据。我假设因为 ParseProcessing 是一个单例 class,所以我只有一份字典。这似乎不正确。我应该如何在 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 单例 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
}

}

检查数据的另一个视图控制器

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

}

}

问题在于 findObjectsInBackgroundWithBlock 是异步方法(即它立即 returns 但在查询完成后稍后调用闭包)。例如,您不能在 loadRecordsFromParse 中 return loadComplete。这个后台请求几乎肯定不会在 loadRecordsFromParse return 秒之前完成。

相反,您可能想要采用 completionHandler 模式。例如,此示例 loadRecords 不会立即尝试 return 任何操作,而是会在请求完成后调用 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!

坦率地说,我倾向于完全摆脱您的单例中的那些属性。当您处理异步代码时,拥有异步更新的 public 属性将成为令人心痛的根源。你可以做,但它不是我的第一选择。

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

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