我正在后臺獲取資料源。有 2 個 url,我用 tabBar 選擇它。要知道我需要訪問哪個 url,我使用navigationController?.tabBarItem.tag. 但它會引發“navigationController 必須僅從主執行緒使用”的錯誤。我試圖用它來包裝它,DispatchQueue.main.async但它沒有用。任何修復或新方法表示贊賞。
override func viewDidLoad() {
super.viewDidLoad()
performSelector(inBackground: #selector(fetchJSON), with: nil)
}
@objc func fetchJSON() {
let urlString: String
if navigationController?.tabBarItem.tag == 0 {a
urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
} else {
urlString = "https://www.hackingwithswift.com/samples/petitions-2.json"
}
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
parse(json: data)
return
}
}
performSelector(onMainThread: #selector(showError), with: nil, waitUntilDone: false)
}
uj5u.com熱心網友回復:
將需要訪問 UI 的邏輯移至主執行緒,然后將結果作為引數傳遞給后臺執行緒上的函式。
這里有幾個問題:
- 這些
performSelector(…)方法非常低級,對于 Swift 來說不是一個好的解決方案。避免這些,他們有問題,并且讓傳遞爭論變得很麻煩。使用 GCD 或async/await代替。 - 使用同步
Data(contentsOf: …)也不是一個好主意。如果您使用異步解決方案,您一開始就不會遇到執行緒問題。
我真的建議你研究第二個問題(例如使用DataTask),因為它完全消除了你的執行緒問題,但這里有一個使用 GCD 重構現有代碼的簡單方法,它應該已經作業:
override func viewDidLoad() {
super.viewDidLoad()
let urlString: String
if navigationController?.tabBarItem.tag == 0 {a
urlString = "https://www.hackingwithswift.com/samples/petitions-1.json"
} else {
urlString = "https://www.hackingwithswift.com/samples/petitions-2.json"
}
DispatchQueue.global(qos: .utility).async {
self.fetchJSON(urlString)
}
}
func fetchJSON(_ urlString: String) {
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
parse(json: data)
return
}
}
DispatchQueue.main.async {
self.showError()
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/495031.html
上一篇:[UINavigationControllerselectedIndex]:發送到UITabBarController實體的無法識別的選擇器
