Ответ
objectWillChange.send() — метод ObservableObject протокола для ручного уведомления SwiftUI об изменениях.
Преимущества:
- Гибкость для сложных свойств: Позволяет уведомлять об изменениях вычисляемых свойств или свойств, которые не могут быть помечены как
@Published. - Групповые обновления: Можно объединить несколько изменений в одно уведомление для оптимизации.
- Работа с внешним кодом: Полезно при интеграции с не-SwiftUI кодом, который меняет состояние объекта.
Недостатки:
- Нет точности: SwiftUI перерисовывает все представления, зависящие от этого объекта, а не только от конкретного свойства.
- Снижение прозрачности: Усложняет понимание потока данных по сравнению с явными
@Publishedсвойствами. - Риск избыточных обновлений: Легко вызвать уведомление, даже когда данные фактически не изменились.
- Обход механизмов SwiftUI: Может мешать работе
@StateObjectили@EnvironmentObject.
Рекомендации и пример:
Используйте @Published по умолчанию. Применяйте objectWillChange.send() только для специальных случаев.
class SettingsViewModel: ObservableObject {
// Стандартное использование @Published
@Published var username: String = ""
// Сложное свойство, требующее ручного уведомления
private var internalScore = 0
var score: Int {
get { internalScore }
set {
// Производим валидацию или логику
if newValue != internalScore && newValue >= 0 {
internalScore = newValue
// Ручное уведомление об изменении
objectWillChange.send()
}
}
}
// Групповое обновление
func resetAll() {
username = ""
internalScore = 0
// Одно уведомление вместо двух
objectWillChange.send()
}
} Ответ 18+ 🔞
Да ты посмотри, какая интересная хуйня! Вот этот objectWillChange.send() — он как запасной аэродром в протоколе ObservableObject. Ну знаешь, когда всё по красоте через @Published не получается.
Чем он хорош, этот ручной костыль?
- Для мозговыносящих свойств: Допустим, у тебя там вычисляемое свойство, которое пляшет с бубном, или геттер/сеттер с логикой. Воткнул
objectWillChange.send()в сеттер — и всё, SwiftUI в курсе дела. - Чтоб не дрочить вьюхи по десять раз: Сделал кучу изменений в модели — и один раз крикнул
objectWillChange.send(). Одно обновление вместо десяти, красота. - Когда снаружи лезет старый код: Какая-нибудь legacy-хрень на Objective-C плюёт в твой объект. Ты ловишь этот плевок и руками отправляешь уведомление: «Эй, SwiftUI, смотри-ка, что тут у нас поменялось!».
А чем он говён?
- Точности — ноль ебать: Ты кричишь «ОБНОВЛЯЙСЯ!», а SwiftUI, как дурак, перерисовывает ВСЁ, что за этим объектом следит. Даже если изменилась одна мелкая хуйня.
- Прозрачность накрылась медным тазом: Глядишь в код — и хуй поймёшь, от чего именно вьюха перерисовывается. Где
@Published— там всё ясно, а тут — загадка, блядь. - Задрочить можно по-страшному: Забыл проверить, а поменялось ли значение на самом деле? Отправил уведомление на ровном месте — и пошла цепочка лишних ререндеров. Пиздец оптимизации.
- Можно сломать родные механизмы: Начинаешь рулить уведомлениями сам — и
@StateObjectс@EnvironmentObjectмогут посмотреть на тебя как на идиота и перестать работать как надо.
Так что делать-то, гений?
Да хуй его знает... Шучу. По умолчанию — всегда @Published. Это святое. А objectWillChange.send() — это как аварийный молоток в стекле. Бьёшь только когда припёрло.
Вот, смотри, как это бывает в жизни:
class SettingsViewModel: ObservableObject {
// Ну тут всё стандартно, красота
@Published var username: String = ""
// А вот свойство с подвохом
private var internalScore = 0
var score: Int {
get { internalScore }
set {
// Тут у нас логика, валидация, ебатория
if newValue != internalScore && newValue >= 0 {
internalScore = newValue
// Ага, изменилось! Кричим вручную!
objectWillChange.send()
}
}
}
// Функция-убийца, сбрасывает всё
func resetAll() {
username = ""
internalScore = 0
// И вместо двух отдельных воплей — один мощный рёв!
objectWillChange.send()
}
}
В общем, инструмент как инструмент. Главное — не начать им всё подряд забивать гвозди, а то потом разбираться будет овердохуища.