我在从服务器(我通过一些PHP Web服务访问的MySQL数据库)中获取异步数据时遇到了一些困难。我的代码如下:
func RetreiveStaff() {
SetProgramMode()
self.astrUsers = [String]()
self.pkvUser.reloadAllComponents()
if self.booCurrentDataVersion == true {
var url:NSURL = NSURL(string: "http://www.website.com.au/retrievestaff.php")!
let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
if error == nil {
let dataArray:[AnyObject] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! [AnyObject]
for data in dataArray {
let dictionary:[String:String] = data as! [String:String]
if dictionary["StaffID"] != nil {
self.astrUsers.append(dictionary["LastName"]! + ", " + dictionary["FirstName"]!)
self.astrUserIDs.append(dictionary["StaffID"]!)
self.pkvUser.reloadAllComponents()
}
self.pkvUser.reloadAllComponents()
}
} else {
let actionSheet:UIAlertController = UIAlertController(title: "Connection Error", message: "\(strAppName) was unable to load data. Check you are connected to the internet and restart the app.", preferredStyle: UIAlertControllerStyle.Alert)
let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
(alertAction:UIAlertAction!) in
})
actionSheet.addAction(firstAlertAction)
self.presentViewController(actionSheet, animated: true, completion: nil)
}
})
task.resume()
}
}
当代码执行时,数据将按原样获取,但视图不会显示它。基本上,正如您所看到的,我抓取数据,将其放入数组中,然后重新加载我的pickerView(它使用数组作为其数据源)。执行代码后,pickerView在约20秒内保持明显空白,然后突然出现。但是,如果用户在20秒内点击,拖动,更改pickerView等的值,则会显示数据。
根据我对问题的理解,这意味着数据被提取并放入pickerView,但视图没有正确重新加载,尽管self.pkvUser.reloadAllComponents()
数量众多且可能过多。
我做错了什么?
(我也检查了这些问题,但他们没有解决问题:
Swift: Asynchronous callback
Asynchronous Fetching Swift Xcode
iOS Swift: Displaying asynchronous data on a TableView)
答案 0 :(得分:3)
在IOS中显示任何视图应始终位于主线程中。
当您执行异步请求时,将结果从主线程推送到用户的视图,如下所示:
ArrayList<? extends Runnable>
尝试此代码,异步请求完成后,处理主队列中的响应没有问题,这也解决了显示滞后
var someView : UIView = someAsyncCallBack..
dispatch_async(dispatch_get_main_queue()) {
currentView.addSubview(someView);
}