@Published: шта је, принцип рада и примена

Аутор: IT Sectr Објављено: 2026-06-19 Време читања: 8 мин

@Published — је property wrapper из framework-а Combine који автоматски објављује промене својства класе која је у складу са протоколом ObservableObject. Када се вредност својства означеног са @Published промени, SwiftUI прима сигнал путем objectWillChange и поново исцртава све view-ове који су претплаћени на овај објекат. Према Apple Combine Framework Documentation (2025), @Published генерише Publisher који се може додатно трансформисати коришћећем оператора Combine: map, filter, debounce и других. То чини @Published кључном везом између података и корисничког интерфејса у архитектури MVVM.

Главно

  • @Published — property wrapper за автоматско објављивање промена својстава ObservableObject у SwiftUI и Combine
  • Механизам: при промени вредности позива се objectWillChange, што покреће поновно исцртавање претплаћених view-ова
  • Publisher је доступан путем пројекције $property — може се претплаћивати, комбиновати и трансформисати ток
  • ObservedObject и StateObject се автоматски претплаћују на @Published својства — ручно претплаћивање није потребно
  • iOS 17+ макро @Observable нуди алтернативу, али @Published остаје стандард за Combine пајплајнове

Шта је @Published?

@Published — је property wrapper дефинисан у модулу Combine који додаје својству класе могућност автоматског обавештавања претплатника о променама. Може се примењивати само унутар класе (не у структури) и само на својства класе која је у складу са протоколом ObservableObject.

Када се вредност @Published својства промени, Combine генерише догађај путем уграђеног publisher-а, доступног путем префикса долара: $propertyName. Овај publisher је ObservableObjectPublisher, који припада самом ObservableObject-у. SwiftUI се автоматски претплаћује на њега када view користи @ObservedObject или @StateObject, и поново исцртава view при свакој промени било којег @Published својства унутар објекта.

Према њизи Мата Њубурга «IOS 18 Programming Fundamentals with Swift» (2025), @Published је практично омотање над pattern-ом willSet, који автоматски позива objectWillChange.send(). Компилер развија @Published у израчунато својство са willSet опсервером, што даје нулти оверхед у радном окружењу у поређењу са ручном имплементацијом.

Користите @Published за сва @Published својства ObservableObject чије промене треба да се одразе у интерфејсу. За својства која не утичу на UI, обичне stored properties без @Published смањују број непотребних поновних исцртавања.

Како ради @Published

@Published генерише два кључна елемента при компилацији. Први — складиштено својство са willSet опсервером који позива objectWillChange.send() пре записивања нове вредности. Други — пројекција $propertyName која враћа Published.Publisher који се може користити директно у Combine пајплајновима.

Размотримо класу Settings са три својства: два @Published и једно обично:

swift
class Settings: ObservableObject {
    @Published var username: String = "Guest"
    @Published var isDarkMode = false
    var lastLogin: Date = Date()  // без @Published
}

При промени username или isDarkMode, SwiftUI поново исцртава све view-ове претплаћене на инстанцу Settings. Промена lastLogin неће покренути поновно исцртавање. Ако желите да ручно обавестите претплатнике о промени обичног својства, можете позвати objectWillChange.send() у willSet опсерверу.

Важан детаљ: @Published објављује промене само при директном уписивању у својство. Ако је својство референциог типа (класа) и његово унутрашње стање се промени без замене референце, @Published то неће приметити. У таквим случајевима потребно је ручно слање догађаја или замена типом вредности (структуром).

@Published и Combine

@Published је чврсто интегрисан са Combine-ом — свако @Published својство автоматски пружа publisher доступан путем пројекције $propertyName. То омогућава примену Combine оператора за филтрирање, трансформацију, комбиновање и каснену обраду вредности.

Типичан сценарио — претрага са debounce-ом. Поље за унос је повезано са @Published својством searchText, али захтев ка серверу треба да се шаље тек након паузе од 300 мс. Combine са $searchText.debounce решава то у једној линији:

swift
class SearchViewModel: ObservableObject {
    @Published var searchText = ""
    @Published var results: [String] = []
    private var cancellables = Set<AnyCancellable>()

    init() {
        setupSearchSubscription()
    }

    private func setupSearchSubscription() {
        $searchText
            .debounce(for: .milliseconds(300), scheduler: RunLoop.main)
            .removeDuplicates()
            .sink { [weak self] text in
                self?.performSearch(text)
            }
            .store(in: &cancellables)
    }

    private func performSearch(_ text: String) { }
}

Према чланку Џона Сандела (Swift by Sundell, 2024), комбиновање @Published са Combine-ом је стандардни pattern за реактивне пајплајнове у SwiftUI апликацијама: validation, debounce, throttle, combineLatest, merge са другим publishers. @Published делује као веза између императивног UI кода и реактивног Combine-а.

@Published напрама @Observable макроа

Са изласком iOS 17, Apple је представила макро @Observable, који нуди алтернативни приступ реактивности без ObservableObject и @Published. @Observable автоматски прати приступ својствима на нивоу читања, не записивања, што даје прецизније поновно исцртавање — ажурира се само онај view који чита конкретно измењено својство.

Међутим, то не значи да је @Published застарео. @Published остаје потребан када је потребна интеграција са Combine пајплајновима — пројекција $propertyName даје publisher-а који @Observable нема. Поред тога, за уназад компатибилност са iOS 16 и старијим верзијама, @Published+ObservableObject је једина опција. Према Apple WWDC 2023 сесији «Discover Observation in SwiftUI», Apple препоручује @Observable за нове пројекте, али експлицитно задржава подршку за @Published за постоћећи код и Combine сценарије.

У пракси, многи пројекти користе хибридни приступ: нови модели података пишу се са @Observable, а постоћећи ObservableObject са @Published остају без рефакторисања. @Published је такође незамењив када је потребна прецизна контрола над објављивањем — на пример, одлагање обавештавања до завршетка групног ажурирања више својстава.

Типичне грешке са @Published

Прва грешка — примена @Published у структури. Компилер ће приказати грешку: «Property wrapper cannot be applied to a computed property» или «'@Published' is only available on members of a class». @Published захтева референцну семантику, јер је ObservableObjectPublisher класа која мора бити јединствена за сваку инстанцу.

Друга грешка — мутација садржаја референцног својства без замене референце. Ако @Published својство има тип низа [String] и позовете array.append("new"), @Published неће приметити промену јер се референца на низ није промењена. Решење: додијелите својству нову вредност array = array + ["new"] или користите objectWillChange.send() ручно.

Трећа грешка — прекомернан број @Published својстава. Свако @Published својство покреће поновно исцртавање свих view-ова претплаћених на ObservableObject, не само оних који читају то својство. Према Point-Free (2025), подела једног великог ObservableObject-а на неколико малих са @StateObject и @EnvironmentObject смањује број непотребних поновних исцртавања и побољшава перформансе.

Примери кода

Први пример — ViewModel формулара за регистрацију са валидацијом. @Published својства email и password покрећу приказ грешака валидације кроз Combine pipeline:

swift
class RegistrationViewModel: ObservableObject {
    @Published var email = ""
    @Published var password = ""
    @Published var emailError: String?
    @Published var isFormValid = false
    private var cancellables = Set<AnyCancellable>()

    init() {
        $email
            .map { $0.contains("@") ? nil : "Invalid email" }
            .assign(to: &$emailError)
            .store(in: &cancellables)

        $email.combineLatest($password)
            .map { !$0.isEmpty && !$1.isEmpty }
            .assign(to: &$isFormValid)
            .store(in: &cancellables)
    }
}

Други пример — ручно објављивање за колекцију референцних елемената. Уместо замене целог низа при свакој промени унутар елемента, користи се objectWillChange.send():

swift
class TodoItem {
    var title: String
    var isDone = false
    init(title: String) { self.title = title }
}

class TodoListViewModel: ObservableObject {
    @Published var items: [TodoItem] = []

    func toggle(item: TodoItem) {
        item.isDone.toggle()
        self.objectWillChange.send()  // ручно обавештавање
    }
}

Трећи пример — Assign на @Published својство путем Combine-а. Користећи нову синтаксу Swift 5.9, може се директно додијелити путем пројекције assign(to: &$property) без Optional омотача. То је најкраћи пут за повезивање publisher-а са @Published својством без креирања претплате.

Често постављана питања

Може ли се @Published користити у структури?

Не, @Published се може примењивати само унутар класе која је у складу са ObservableObject. У структурама користите @State за локално стање или @Bindable са @Observable макром у iOS 17+. Покушај примене @Published у структури изазваће грешку компилације.

Како @Published ради са низовима и речницима?

Исправно: додијељивајте нову вредност у целини (array = array + ["new"]). @Published прати замену референце, не мутацију садржаја. За колекције референцних типова користите ручни позив objectWillChange.send() након мутације унутрашњег стања елемената.

По чему се @Published разликује од @State?

@State је намењен за локално стање унутар једног view-а и ради само са типовима вредности. @Published — за ObservableObject својства која могу читати више view-ова путем @ObservedObject или @EnvironmentObject. @State је једноставнији, @Published је моћнији захваљујући интеграцији са Combine-ом.

Да ли је @Published потребан за свако ObservableObject својство?

Само за она чије промене треба да ажурирају UI. Својства за унутрашње израчуне, кеш или привремене заставице не захтевају @Published — то смањује број непотребних поновних исцртавања. Користите @Published као сигнал «ово својство је важно за интерфејс».

Како @Published ради са Core Data?

SwiftUI се интегрише са Core Data путем @FetchRequest и @ObservedObject за NSManagedObject. ManagedObject је већ у складу са ObservableObject, па @Published није потребан — NSManagedObject сам обавештава о променама. @Published се користи у ViewModel слоју између Core Data и UI за трансформацију података.

Закључак

  • @Published — property wrapper из Combine-а, автоматски објављује промене ObservableObject својстава за SwiftUI и Combine пајплајнове
  • Механизам: willSet опсервер позива objectWillChange.send(), генеришући publisher кроз пројекцију $property
  • Combine: @Published даје publisher за debounce, map, combineLatest и друге операторе — то је веза између UI и реактивних пајплајнова
  • @Observable (iOS 17+) — алтернатива за нове пројекте, али @Published остаје стандард за Combine и уназад компатибилност
  • Грешке: @Published не ради у структурама, не прати мутацију референцних типова, прекомернан број @Published повећава поновна исцртавања
  • Best practice: означавајте @Published само својства која утичу на UI, делите велике ObservableObject-е на неколико малих
  • Assign: assign(to: &$property) у Swift 5.9 омогућава директно претплаћивање publisher-а на @Published својство

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође