swift - How do I share variables inside a singleton class -


i trying create common class storing , retrieving data in parse. made parseprocessing class singleton class. main view controller load data , store dictionary in parseprocessing. creating shared instance of parseprocessing class. view controller try access data dictionary. assumed because parseprocessing singleton class have single copy of dictionary. not appear correct. how should declare variables inside parseprocessing shared? code shown below:

import uikit  var gsep = ","  class qwikfileviewcontroller: uiviewcontroller {  var loaddata = parseprocessing.sharedinstance  override func viewdidload() {     super.viewdidload()      // load data 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 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 {             // find succeeded.             println("successfully retrieved \(objects!.count) items.")             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 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 = ""             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 }  } 

another view controller examine data

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

the problem findobjectsinbackgroundwithblock asynchronous method (i.e. returns closure called later when query done). cannot return loadcomplete in loadrecordsfromparse, example. background request never done time loadrecordsfromparse returns.

instead, want adopt completionhandler pattern. example, sample loadrecords doesn't try return immediately, rather call completionhandler when request done.

func loadrecords(completionhandler:([someobject]?, nserror?) -> ()) {     let query = pfquery(classname: "someclass")      query.findobjectsinbackgroundwithblock { objects, error in         // build model object         completionhandler(objectarray, error)     } } 

and you'd call so:

loaddata.loadrecords() { objects, error in     // use `objects` (and make sure `error` `nil`) here }  // not use variables here, above closure has not run yet! 

frankly, i'd inclined rid of properties in singleton altogether. when you're dealing asynchronous code, have public properties updated asynchronously going source of heartache. can it, wouldn't first choice.

for example, when testviewcontroller presented, cannot assume asynchronous fetch associated dictmenulist done yet. @ , wonder if makes sense testviewcontroller initiate fetch , use dictmenulist in completion handler. that's going easiest.

if must initiate asynchronous request 1 view controller , have view controller informed when asynchronous request done, might have use other pattern, such notifications (e.g. use nsnotificationcenter, , have singleton post notifications when various requests done, , view controller needs informed of fact can add observers notification).


Comments