我正在尝试创建一个用于在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()
}
}
答案 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
,并在完成各种请求时发出单例发布通知,然后需要通知此事实的任何视图控制器都可以将自己添加为该通知的观察者。)