我有一个应用程序从在线JSON文件加载UIPickerView选项,虽然它能够成功地执行它,它非常慢,我想知道为什么。控制台在2秒内打印JSON文件,但除非我手动移动它,否则它会在选择器视图中显示12秒以上。如何让PickerView更快地加载选项而无需手动移动它来显示选项?
以下是我的代码部分:
import UIKit
class FirstViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var mypickerview: UIPickerView!
var pickerData: [String] = [String]()
override func viewDidLoad() {
super.viewDidLoad()
/*Begin Loading the list*/
let postEndpoint: String = "https://example.com/json.json"
let session = NSURLSession.sharedSession()
let url = NSURL(string: postEndpoint)!
session.dataTaskWithURL(url, completionHandler: { ( data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
guard let realResponse = response as? NSHTTPURLResponse where
realResponse.statusCode == 200 else {
print("Not a 200 response")
return
}
do {
if let ipString = NSString(data:data!, encoding: NSUTF8StringEncoding) {
print(ipString)
let jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary
let One = jsonDictionary["One"] as! String
let Two = jsonDictionary["Two"] as! String
let Three = jsonDictionary["Three"] as! String
let Four = jsonDictionary["Four"] as! String
self.mypickerview.delegate = self
self.mypickerview.dataSource = self
self.pickerData = [One, Two, Three, Four]
self.mypickerview.reloadAllComponents()
self.mypickerview.delegate = self;
}
} catch {
print("bad things happened")
}
}).resume()
/*End Loading the list*/
答案 0 :(得分:2)
您必须始终在主队列上调用ReloadAllcompenents()
,因为它会更新您的视图。 dispatch_async应该可以解决问题。希望它有所帮助
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
dispatch_async(dispatch_get_main_queue()) {
self.mypickerview.reloadAllComponents()
}
}
答案 1 :(得分:0)
您正在后台队列上重新加载选择器。 UI更改的大延迟是这种情况的常见症状。您需要将UI工作(涉及选择器的任何内容)分派到主队列。
在会话的委托队列上调用URL会话任务的完成处理程序,该队列不是主队列。
答案 2 :(得分:0)
Dispatch.main.async
- 更新pickerView
上的MAIN queue
。
根据我watchos
的经验,每当我更新sessionDataTask
completionBlock中的UI时,它都是缓慢的,直到我在主队列上执行它。
换句话说,您可以在任何线程或队列上创建sessionDataTask
,但在completionBlock中,在主队列/线程上调度它。您应该始终在mainQueue上更新UI。
let session = URLSession.shared
let url = URL(string: "https://example.com")!
session.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
if let ipString = String(data: data!, encoding: String.Encoding.utf8) {
if let jsonDictionary = try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) {
DispatchQueue.main.async { //dispatch_async on MainQueue.
let One = jsonDictionary["One"] as! String
let Two = jsonDictionary["Two"] as! String
let Three = jsonDictionary["Three"] as! String
let Four = jsonDictionary["Four"] as! String
self.mypickerview.delegate = self
self.mypickerview.dataSource = self
self.pickerData = [One, Two, Three, Four]
self.mypickerview.reloadAllComponents()
}
}
}
}