如何克服导航到其他 viewcontroller iOS swift 时的延迟?
How to overcome delay in navigation to other viewcontroller iOS swift?
我最近停止使用 Alamofire
进行 HTTP 网络调用,现在 swift 4 Apple 引入了 Codable
-协议,与 [=16 相比,它非常强大且快速=].一切都按预期正常工作,甚至我的反应比以前更快。但是有一个问题。在使用 Codable
协议解析数据之前,我导航到其他视图的速度非常快。但是现在我的导航有轻微的延迟,特别是当导航到我使用 JSONDecoder
获得响应的页面时。例如:我有 VC1 和 VC2,VC1 是一个静态页面,在 VC2 中我使用 JSONDecoder
并获取一些数据并将其显示在 collectionView
中。现在我在 VC1 中单击一个按钮,它在转到 VC2 之前只停止了一秒钟。我不知道为什么会这样。
VC1 中的代码:
@IBAction func gotoProductCollectionView(_ sender: UIButton) {
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "productCollection") as! ProductCollectionViewController
self.navigationController?.pushViewController(viewController, animated: true)
}
VC2 中的代码:
class ProductCollectionViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
@IBOutlet weak var productsTableView: UITableView!
var productsData = [ProductData]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getProductData()
}
func getProductData() {
self.productsData = []
guard let productDataURL = URL(string: "MyURL") else {return}
DispatchQueue.global(qos: .background).async {
do {
let data = try Data(contentsOf: productDataURL)
self.productsData = try
JSONDecoder().decode([ProductData].self, from: data)
print(self.productsData)
print(self.productsData.count)
for productNames in self.productsData {
print(productNames.product_name!)
}
}catch let error {
print(error)
}
DispatchQueue.main.async {
self.productsTableView.reloadData()
}
}
}
}
产品模型对象:
struct ProductData: Codable {
var product_id: String?
var product_name: String?
var product_price: String?
var product_special_price: String?
var product_sale_of: String?
var product_brand: String?
var product_image: String?
private enum CodingKeys: String, CodingKey {
case product_id
case product_name
case product_price
case product_special_price
case product_sale_of
case product_brand
case product_image
}
init(product_id: String? = nil, product_name: String? = nil, product_price: String? = nil, product_special_price: String? = nil, product_sale_of: String? = nil, product_brand: String? = nil, product_image: String? = nil) {
self.product_id = product_id
self.product_name = product_name
self.product_price = product_price
self.product_special_price = product_special_price
self.product_sale_of = product_sale_of
self.product_brand = product_brand
self.product_image = product_image
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
product_id = try container.decode(String.self, forKey: .product_id)
product_name = try container.decode(String.self, forKey: .product_name)
product_price = try container.decode(String.self, forKey: .product_price)
product_special_price = try container.decode(String.self, forKey: .product_special_price)
product_brand = try container.decode(String.self, forKey: .product_brand)
product_image = try container.decode(String.self, forKey: .product_image)
if let value = try? container.decode(Int.self, forKey: .product_sale_of) {
product_sale_of = String(value)
} else {
product_sale_of = try container.decode(String.self, forKey: .product_sale_of)
}
}
}
答案在这一行
let data = try Data(contentsOf: productDataURL)
很明显,您在 DispatchQueue.main
中从互联网下载数据
您需要在单独的后台队列中执行此操作,然后再次从 main
更新视图。不要忘记使用 .async
调用。
我最近停止使用 Alamofire
进行 HTTP 网络调用,现在 swift 4 Apple 引入了 Codable
-协议,与 [=16 相比,它非常强大且快速=].一切都按预期正常工作,甚至我的反应比以前更快。但是有一个问题。在使用 Codable
协议解析数据之前,我导航到其他视图的速度非常快。但是现在我的导航有轻微的延迟,特别是当导航到我使用 JSONDecoder
获得响应的页面时。例如:我有 VC1 和 VC2,VC1 是一个静态页面,在 VC2 中我使用 JSONDecoder
并获取一些数据并将其显示在 collectionView
中。现在我在 VC1 中单击一个按钮,它在转到 VC2 之前只停止了一秒钟。我不知道为什么会这样。
VC1 中的代码:
@IBAction func gotoProductCollectionView(_ sender: UIButton) {
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "productCollection") as! ProductCollectionViewController
self.navigationController?.pushViewController(viewController, animated: true)
}
VC2 中的代码:
class ProductCollectionViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
@IBOutlet weak var productsTableView: UITableView!
var productsData = [ProductData]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getProductData()
}
func getProductData() {
self.productsData = []
guard let productDataURL = URL(string: "MyURL") else {return}
DispatchQueue.global(qos: .background).async {
do {
let data = try Data(contentsOf: productDataURL)
self.productsData = try
JSONDecoder().decode([ProductData].self, from: data)
print(self.productsData)
print(self.productsData.count)
for productNames in self.productsData {
print(productNames.product_name!)
}
}catch let error {
print(error)
}
DispatchQueue.main.async {
self.productsTableView.reloadData()
}
}
}
}
产品模型对象:
struct ProductData: Codable {
var product_id: String?
var product_name: String?
var product_price: String?
var product_special_price: String?
var product_sale_of: String?
var product_brand: String?
var product_image: String?
private enum CodingKeys: String, CodingKey {
case product_id
case product_name
case product_price
case product_special_price
case product_sale_of
case product_brand
case product_image
}
init(product_id: String? = nil, product_name: String? = nil, product_price: String? = nil, product_special_price: String? = nil, product_sale_of: String? = nil, product_brand: String? = nil, product_image: String? = nil) {
self.product_id = product_id
self.product_name = product_name
self.product_price = product_price
self.product_special_price = product_special_price
self.product_sale_of = product_sale_of
self.product_brand = product_brand
self.product_image = product_image
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
product_id = try container.decode(String.self, forKey: .product_id)
product_name = try container.decode(String.self, forKey: .product_name)
product_price = try container.decode(String.self, forKey: .product_price)
product_special_price = try container.decode(String.self, forKey: .product_special_price)
product_brand = try container.decode(String.self, forKey: .product_brand)
product_image = try container.decode(String.self, forKey: .product_image)
if let value = try? container.decode(Int.self, forKey: .product_sale_of) {
product_sale_of = String(value)
} else {
product_sale_of = try container.decode(String.self, forKey: .product_sale_of)
}
}
}
答案在这一行
let data = try Data(contentsOf: productDataURL)
很明显,您在 DispatchQueue.main
您需要在单独的后台队列中执行此操作,然后再次从 main
更新视图。不要忘记使用 .async
调用。