幾天來我一直在嘗試理解并弄清楚它,但仍然無法提出解決方案。
例如,有一個核心資料物體有 1 百萬行,我想在視圖中顯示所有記錄,并帶有“滾動時加載”以提高性能,因為加載時加載 1 百萬行會很慢并且浪費。
從檔案中基本上.fetchBatchSize只會在需要時加載“批量”資料,這是解決問題的完美解決方案。用戶滾動串列,SwiftUI 在需要時分批加載資料。
這是我所擁有的(簡化):
ContextView.swift
struct ContentView: View {
@FetchRequest private var items: FetchedResults<Item>
init() {
_items = FetchRequest<Item>(fetchRequest: request())
}
var body: some View {
List(items) {
Text($0.name)
}
}
func request() -> NSFetchRequest<Item> {
let request = Item.fetchRequest()
request.sortDescriptors = []
request.fetchBatchSize = 5
return request
}
}
問題:@FetchRequest 在沒有批處理的情況下同時加載所有記錄和/或它確實作業但同時檢索所有批次并且破壞了批處理檢索的整個目的。
我嘗試實際加載 1 百萬行并花費大量時間來顯示視圖(因為它正在檢索和準備所有 1 百萬行資料)。如果 '.fetchBatchSize' 作業,它只會加載前 5 個,并且會隨著串列滾動而緩慢加載。
*注意:我知道有.fetchLimit& .fetchOffset,但它需要實作一個單獨的邏輯 *
uj5u.com熱心網友回復:
您不能使用fetchBatchSize,因為List需要objectIDSwiftUI 差異來檢測插入、洗掉和移動的所有 s。這就是為什么如果您設定比沒有批處理慢得多的批處理大小,它會加載所有批處理的原因。
但是,您可以禁用includesPropertyValues以防止 Core Data 將所有資料加載到其行快取中。
禁用它后,SQL 查詢變為:
SELECT 0, t0.Z_PK FROM ZITEM t0
而不是默認的啟用它獲取所有欄位:
SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME, t0.ZTIMESTAMP FROM ZITEM t0
要查看查詢,請使用啟動引數-com.apple.CoreData.SQLDebug 4(數字越大,日志輸出越多)。
你還可以利用 List 的惰性行為,將 移動$0.name到子 View 的主體中,這樣 Core Data 只會在資料庫中讀取資料并在物件滾動到螢屏上時觸發物件的錯誤。
這兩項改進可能會給性能帶來足夠大的提升,看起來像這樣:
extension Item {
static func myFetchRequest() -> NSFetchRequest<Item> {
let fr = Self.fetchRequest()
fr.includesPropertyValues = false
fr.sortDescriptors = [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)]
return fr
}
}
struct MyView: View {
@ObservedObject var item: Item
var body: some View {
Text(item.timestamp!, formatter: itemFormatter)
}
}
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
fetchRequest: Item.myFetchRequest(),
animation: .default)
private var items: FetchedResults<Item>
var body: some View {
NavigationView {
List {
ForEach(items) { item in
MyView(item: item)
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/431354.html
