我想知道是否有人可以提供有關如何在 Swift 中特別密集的功能(在主執行緒上)期間“強制”更新 UI 的建議。
解釋一下:我正在嘗試向我的應用程式添加一個“匯入”功能,這將允許用戶從備份檔案中匯入專案(可以是 1 - 1,000,000 條記錄,例如,取決于他們備份的大小)保存到應用程式的 CodeData 資料庫中。此函式使用“for in”回圈(回圈遍歷備份檔案中的每條記錄),并且對于該回圈中的每個“for”,該函式都會向委托(ViewController)發送一條訊息,以使用進度更新其 UIProgressBar這樣用戶就可以在螢屏上看到實時進度。我通常會嘗試將這個密集型函式發送到后臺執行緒,并在主執行緒上單獨更新 UI……但這不是
代碼的簡化版本是:
class CoreDataManager {
var delegate: ProgressProtocol?
// (dummy) backup file array for purpose of this example, which could contain 100,000's of items
let backUp = [BackUpItem]()
// intensive function containing 'for in' loop
func processBackUpAndSaveData() {
let totalItems: Float = Float(backUp.count)
var step: Float = 0
for backUpItem in backUp {
// calculate Progress and tell delegate to update the UIProgressView
step = 1
let calculatedProgress = step / totalItems
delegate?.updateProgressBar(progress: calculatedProgress)
// Create the item in CoreData context (which must be done on main thread)
let savedItem = (context: context)
}
// loop is complete, so save the CoreData context
try! context.save()
}
}
// Meanwhile... in the delegate (ViewController) which updates the UIProgressView
class ViewController: UIViewController, ProgressProtocol {
let progressBar = UIProgressView()
// Delegate function which updates the progress bar
func updateProgressBar(progress: Float) {
// Print statement, which shows up correctly in the console during the intensive task
print("Progress being updated to \(progress)")
// Update to the progressBar is instructed, but isn't reflected on the simulator
progressBar.setProgress(progress, animated: false)
}
}
需要注意的一件重要事情:上面代碼中的列印陳述句運行良好/按預期運行,即在整個長“for in”回圈(可能需要一兩分鐘)中,控制臺不斷顯示所有列印陳述句(顯示不斷增加的進度值),所以我知道委托 'updateProgressBar' 函式肯定是正確觸發的,但是螢屏上的進度條本身根本沒有更新/沒有改變......我假設這是因為 UI 被凍結并且鑒于主要功能運行的強度,沒有“時間”(因為想要一個更好的詞)來反映更新的進度。
我對編碼相對較新,因此如果我要求對任何回復進行澄清,請提前道歉,因為其中大部分內容對我來說都是新的。如果相關,我使用的是 Storyboards(而不是 SwiftUI)。
只是真的在尋找關于是否有任何(相對簡單的)路線來解決這個問題的任何建議/技巧,并且在這個密集的任務期間基本上“強制”用戶界面更新。
uj5u.com熱心網友回復:
你說“......只是真的在尋找關于是否有任何(相對簡單的)路線來解決這個問題的任何建議/技巧,并且基本上'強制'在這個密集的任務期間更新用戶界面。”
不會。如果你在主執行緒上同步做耗時的作業,你會阻塞主執行緒,直到你的代碼回傳,UI 更新才會生效。
您需要弄清楚如何在后臺執行緒上運行您的代碼。我已經有一段時間沒有使用 CoreData 了。我知道可以在后臺執行緒上執行 CoreData 查詢,但我不再記得細節。這就是你需要做的。
至于您對列印陳述句的評論,這是有道理的。Xcode 控制臺與您的應用程式的運行回圈是分開的,即使您的代碼沒有回傳,它也能夠顯示輸出。但是,應用程式 UI 無法做到這一點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382680.html
