我们说我有以下异步查询:
var kittens: [PFObject]!
self.tempView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "pushToView"))
var query = PFQuery(className: "Kittens")
query.findObjectsInBackgroundWithBlock({ (objects, error) in
if let kittenObjects = objects as? [PFObject] {
self.kittens = kittenObjects
}
})
我有一个提供视图控制器的方法:
func pushToView() {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController: KittensViewController = mainStoryboard.instantiateViewControllerWithIdentifier("kittensViewController") as! KittensViewController
viewController.kittens = self.kittens
self.presentViewController(viewController, animated: true, completion: nil)
}
因为我在异步查询块中设置了self.kittens
,所以当我尝试在呈现的视图控制器中访问self.kittens
时,它显然不起作用(它是' s总是空的。)
获得这样的工作的最佳方法是什么?
答案 0 :(得分:1)
有几种选择。主要的是您需要在查询完成时更新KittensViewController
。
在视图控制器中创建KittensViewController
一个包含小猫数组的属性。查询完成后,您不仅会更新self.kittens
,还会更新self.kittensViewController.kittens = kittenObjects
。这不是最好的设计,但应该有效。
更好的设计是将查询放在一个自己的控制器类中,在完成后触发NSNotification。然后,当新的小猫到达并更新您的视图时,您可以在代码的任何位置收听。
var query = PFQuery(className: "Kittens")
query.findObjectsInBackgroundWithBlock({ (objects, error) in
if let kittenObjects = objects as? [PFObject] {
dispatch_async(dispatch_get_main_queue()) {
NSNotificationCenter.defaultCenter().postNotificationName("KittensQueryDidFinish", object:kittenObjects, userInfo:dataDict))
}
})
在viewDidLoad
添加以下内容:
NSNotificationCenter.defaultCenter().addObserverForName("KittensQueryDidFinish", object: nil, queue: NSOperationQueue.mainQueue) { note in
let kittens = note.object
[weak self].kittens = kittens
}
使用该方法,您可以随时随地获得更新。现在,您必须在已经加载小猫时解决问题。因此,我建议您引入一个共享控制器对象(也就是单例)来执行查询并存储小猫。然后你可以从任何地方访问小猫。
答案 1 :(得分:1)
如果var kittens: [PFObject]!
是您的viewController的属性,我认为实现您想要的最简单的方法就是这样声明:
var kittens: [PFObject]! {
didSet {
dispatch_async(dispatch_get_main_queue(), { [weak self] in
if let strongSelf = self {
strongSelf.pushToView()
}
})
}
因此,每次设置小猫时,它都会执行pushToView()
功能。你必须改变这一行:
self.tempView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "pushToView"))
执行查询而不是pushToView()
。例如:
self.tempView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "performFetch"))
当然,您需要创建函数:
func performFetch() {
var query = PFQuery(className: "Kittens")
query.findObjectsInBackgroundWithBlock({ (objects, error) in
//should be created weak self to avoid retain cycles
if let kittenObjects = objects as? [PFObject] {
self.kittens = kittenObjects
}
})
}
但如果小猫不是属性,则可以创建performFetch()
函数,更改手势识别器并在使用self.pushToView()
设置小猫后添加dispatch_async dispatch_get_main_queue()
(如didSet
因为你需要更新主队列中的UI。