如何在单例中共享变量 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 通知,然后任何需要通知此事实的视图控制器都可以将自己添加为该通知的观察者)。
我正在尝试创建一个通用 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 通知,然后任何需要通知此事实的视图控制器都可以将自己添加为该通知的观察者)。