При работе с SwiftData вставка нового объекта в контекст моей модели блокирует мой основной поток. Как избежать лагов?IOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 При работе с SwiftData вставка нового объекта в контекст моей модели блокирует мой основной поток. Как избежать лагов?

Сообщение Anonymous »

Я работаю над своим первым приложением для iOS. У меня есть кнопка, которая при нажатии изменяет переменную состояния, что, в свою очередь, вызывает выполнение блока кода в фоновом потоке. Этот код заканчивается созданием нового объекта, который затем сохраняется в постоянной памяти путем вставки в мой modelContext через modelContext.insert(myObject)
Я заметил заметную задержку пользовательского интерфейса, когда я нажмите эту кнопку. После длительного тестирования и отладки я обнаружил, что узким местом является modelContext.insert(myObject). Если я пропущу эту строку кода и оставлю все остальное как есть, моя кнопка будет работать отлично, и задержка будет равна 0. Как только я снова добавляю эту строку кода, я замечаю значительную задержку.
Что происходит и как я могу устранить задержку пользовательского интерфейса, сохраняя при этом вновь созданный объект в постоянной памяти?
Я пробовал переместить modelContext.insert(myObject) в различные части моего кода, но независимо от того, где я его размещаю, в ту минуту, когда это выполняется, мой пользовательский интерфейс зависает на 0,5–1 с, пока не завершится. . Я не хочу, чтобы мой пользовательский интерфейс зависал
Это моя кнопка запуска. «количество» здесь — это переменная @Binding, полученная из моего родительского представления
Button(action: {
quantity += 1
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
}) {
Image(systemName: "plus.circle.fill")
.font(.largeTitle)
}
.padding(.trailing)

}
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.2))
.cornerRadius(10)

В моем родительском представлении «количество» — это переменная @State. Изменение этой переменной запускает следующий код
.onChange(of: quantity) { oldValue, newValue in

// if didCardVariantChange is true, reset variable and then do nothing
guard !didCardVariantChange else {
didCardVariantChange = false
return
}
didCardVariantChange = false // reset variable

workItem?.cancel() // Cancel previous work if any
let cardID = viewSetCardData.card_ids[indexVar]
workItem = DispatchWorkItem {

let isCardInCollection = Collection.contains(where: { $0.card_id == cardID })

// Add or update the card in collection as necessary
DispatchQueue.global(qos: .background).async {

if newValue > 0 && !isCardInCollection {
memory_operations.shared.addNewCardToCollection(cardIDToAdd: cardID,
selectedCategory: selectedCardCategory,
selectedVariant: selectedCardVariant,
quantity: newValue,
modelContext: modelContext,
cardsArray: allCards)
}
}

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: workItem!)

Ниже приведена функция для Memory_operations.shared.addNewCardToCollection, упомянутая выше
func addNewCardToCollection(cardIDToAdd: String, selectedCategory: String, selectedVariant: String = "Primary Variant", quantity: Int, pricePaid: Double? = nil, modelContext: ModelContext, cardsArray: [CardData]) {

var allVariantsList: [String?] = []
for card in cardsArray where card.id == cardIDToAdd {
allVariantsList = card.allVariants
}

let newCard = CardsOwned(card_id: cardIDToAdd, allVariants: allVariantsList)
newCard.addQuantity_v2(quantity, selectedCategory: selectedCategory, selectedVariant: selectedVariant, unitPrice: pricePaid)

DispatchQueue.main.async {
modelContext.insert(newCard) //Issue occurs at this line. Removing this line results in no UI freezing or lag. Adding this line back in, results in a noticeable lag under the same conditions
try? modelContext.save()
}

}


Подробнее здесь: https://stackoverflow.com/questions/791 ... s-blocking
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Вставка нового объекта в контекст моей модели блокирует мой основной поток. Как избежать лагов?
    Anonymous » » в форуме IOS
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • Сопрограмма Kotlin в Dispatchers.Main не блокирует основной поток
    Гость » » в форуме Android
    0 Ответы
    40 Просмотры
    Последнее сообщение Гость
  • NSRunLoop::runUntilDate блокирует основной поток?
    Anonymous » » в форуме IOS
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • NSRunLoop::runUntilDate блокирует основной поток?
    Anonymous » » в форуме IOS
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Почему мой асинхронный контроллер веб-API ASP.NET блокирует основной поток?
    Anonymous » » в форуме C#
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous

Вернуться в «IOS»