Я работаю над своим первым приложением для 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 ... ead-how-to
Вставка нового объекта в контекст моей модели блокирует мой основной поток. Как избежать лагов? ⇐ IOS
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Почему мой асинхронный контроллер веб-API ASP.NET блокирует основной поток?
Anonymous » » в форуме C# - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-