@Published, ObservableObject protokolüne uyan bir sınıfın özelliğindeki değişiklikleri otomatik olarak yayınlayan Combine framework'ünden bir property wrapper'dır. @Published ile işaretlenmiş bir özelliğin değeri değiştiğinde, SwiftUI objectWillChange aracılığıyla bir sinyal alır ve bu nesneye abone olan tüm görünümleri yeniden çizer. Apple Combine Framework Dokümantasyonu'na (2025) göre @Published, map, filter, debounce ve diğer Combine operatörleri aracılığıyla dönüştürülebilen bir Publisher oluşturur. Bu, @Published'i MVVM mimarisinde veri ve kullanıcı arayüzü arasında önemli bir köprü haline getirir.
Önemli Noktalar
objectWillChange çağrılır ve abone olunan görünümlerin yeniden çizilmesini tetikler$property projeksiyonu aracılığıyla erişilebilir — akışa abone olma, birleştirme ve dönüştürme yapılabilir@Published, Combine modülünde tanımlanmış bir property wrapper'dır ve bir sınıf özelliğindeki değişiklikler hakkında aboneleri otomatik olarak bilgilendirme yeteneği ekler. Yalnızca bir sınıfın içinde (bir yapıda değil) ve yalnızca ObservableObject protokolüne uyan bir sınıfın özelliklerinde kullanılabilir.
Bir @Published özelliğinin değeri değiştiğinde, Combine dolar öneki aracılığıyla erişilebilen yerleşik bir publisher aracılığıyla bir olay oluşturur: $propertyName. Bu publisher, ObservableObject'in kendisine ait olan bir ObservableObjectPublisher'dır. SwiftUI, bir görünüm @ObservedObject veya @StateObject kullandığında otomatik olarak buna abone olur ve nesne içindeki herhangi bir @Published özelliği değiştiğinde görünümü yeniden çizer.
Matt Neuburg'un “IOS 18 Programming Fundamentals with Swift” (2025) kitabına göre @Published, willSet deseninin üzerinde kullanışlı bir sarmalayıcıdır ve otomatik olarak objectWillChange.send() çağrısını yapar. Aslında derleyici, @Published'i willSet gözlemcisi olan hesaplanmış bir özelliğe genişletir ve manuel uygulamaya kıyasla sıfır çalışma zamanı yükü sağlar.
Değişiklikleri arayüze yansıtılması gereken tüm ObservableObject özellikleri için @Published kullanın. Kullanıcı arayüzünü etkilemeyen özellikler için @Published olmadan normal depolanmış özellikler gereksiz yeniden çizmeleri azaltır.
@Published derleme zamanında iki temel öğe oluşturur. Birincisi, yeni değeri yazmadan önce objectWillChange.send() çağıran bir willSet gözlemcisine sahip depolanmış bir özelliktir. İkincisi, doğrudan Combine boru hatlarında kullanılabilen bir Published.Publisher döndüren $propertyName projeksiyonudur.
Üç özelliği olan Settings sınıfını düşünün: ikisi @Published ve biri normal:
class Settings: ObservableObject {
@Published var username: String = "Guest"
@Published var isDarkMode = false
var lastLogin: Date = Date() // without @Published
}
username veya isDarkMode değiştiğinde, SwiftUI Settings örneğine abone olan tüm görünümleri yeniden çizecektir. lastLogin değişikliği yeniden çizmeyi tetiklemez. Normal bir özellikteki değişiklik hakkında aboneleri manuel olarak bilgilendirmeniz gerekiyorsa, willSet gözlemcisinde objectWillChange.send() çağırabilirsiniz.
Önemli bir detay: @Published yalnızca bir özellik doğrudan atandığında değişiklikleri yayınlar. Özellik bir referans türü (sınıf) ise ve referans değiştirilmeden iç durumu değişirse, @Published bunu algılamaz. Bu gibi durumlarda, manuel olay gönderme veya bir değer türüne (yapı) geçiş yapılması gerekir.
@Published, Combine ile sıkı bir şekilde entegre edilmiştir — her @Published özelliği, $propertyName projeksiyonu aracılığıyla erişilebilen bir publisher'ı otomatik olarak sağlar. Bu, filtreleme, dönüştürme, birleştirme ve gecikmeli değer işleme için Combine operatörlerinin kullanılmasına olanak tanır.
Tipik bir senaryo, debounce ile aramadır. Bir giriş alanı @Published özelliği searchText öğesine bağlıdır, ancak sunucu isteği yalnızca 300 ms'lik bir duraklamadan sonra gönderilmelidir. $searchText.debounce ile Combine bunu tek satırda çözer:
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) { }
}
John Sundell'in makalesine (Swift by Sundell, 2024) göre, @Published'i Combine ile birleştirmek, SwiftUI uygulamalarındaki reaktif boru hatları için standart bir desendir: doğrulama, debounce, throttle, combineLatest, diğer publisher'larla birleştirme. @Published, buyruk UI kodu ile reaktif Combine arasında bir köprü görevi görür.
iOS 17'nin piyasaya sürülmesiyle Apple, ObservableObject ve @Published olmadan reaktiviteye alternatif bir yaklaşım sunan @Observable makrosunu tanıttı. @Observable, yazma düzeyi yerine okuma düzeyinde özelliklere erişimi otomatik olarak izler ve daha hassas yeniden çizimler sağlar — yalnızca belirli bir değiştirilmiş özelliği okuyan görünüm güncellenir.
Ancak bu, @Published'in kullanımdan kaldırıldığı anlamına gelmez. Combine boru hattı entegrasyonu gerektiğinde @Published gerekli olmaya devam eder — $propertyName projeksiyonu, @Observable'de olmayan bir publisher sağlar. Ayrıca, iOS 16 ve altı ile geriye dönük uyumluluk için @Published+ObservableObject tek seçenektir. Apple WWDC 2023 oturumu “Discover Observation in SwiftUI”ye göre Apple, yeni projeler için @Observable'ı önerir, ancak mevcut kod ve Combine senaryoları için @Published desteğini açıkça korur.
Pratikte birçok proje hibrit bir yaklaşım kullanır: yeni veri modelleri @Observable kullanırken, @Published ile mevcut ObservableObject'ler yeniden düzenleme yapılmadan kalır. @Published, yayınlama üzerinde ince ayarlı kontrol gerektiğinde de vazgeçilmezdir — örneğin, birden çok özelliğin toplu güncellemesi tamamlanana kadar bildirimi geciktirmek.
İlk hata, bir yapıda @Published kullanmaktır. Derleyici bir hata verecektir: “Property wrapper cannot be applied to a computed property” veya “‘@Published’ is only available on members of a class.” @Published, referans semantiği gerektirir çünkü ObservableObjectPublisher, her örnek için benzersiz olması gereken bir sınıftır.
İkinci hata, referansı değiştirmeden bir referans özelliğinin içeriğini değiştirmektir. Bir @Published özelliği dizi türünde [String] ise ve array.append("yeni") çağrısı yaparsanız, @Published değişikliği algılamaz çünkü diziye olan referans değişmemiştir. Çözüm: özelliğe yeni bir değer atayın array = array + ["yeni"] veya manuel olarak objectWillChange.send() kullanın.
Üçüncü hata, aşırı sayıda @Published özelliğidir. Her @Published özelliği, yalnızca bu özelliği okuyan görünümleri değil, ObservableObject'e abone olan tüm görünümlerin yeniden çizilmesini tetikler. Point-Free (2025)'e göre, büyük bir ObservableObject'i @StateObject ve @EnvironmentObject ile birkaç küçük ObservableObject'e bölmek gereksiz yeniden çizmeleri azaltır ve performansı artırır.
İlk örnek, doğrulama içeren bir kayıt formu ViewModel'idir. @Published özellikleri email ve password, bir Combine boru hattı aracılığıyla doğrulama hata görüntülemesini tetikler:
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)
}
}
İkinci örnek, referans öğelerinden oluşan bir koleksiyon için manuel yayınlamadır. Bir öğe içindeki her değişiklikte tüm diziyi değiştirmek yerine, objectWillChange.send() kullanılır:
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() // manual notification
}
}
Üçüncü örnek, Combine aracılığıyla bir @Published özelliğine Assign yapmaktır. Swift 5.9'un yeni sözdizimini kullanarak, Optional sarmalayıcı olmadan assign(to: &$property) projeksiyonu aracılığıyla doğrudan atama yapabilirsiniz. Bu, bir abonelik oluşturmadan bir publisher'ı @Published özelliğine bağlamanın en kısa yoludur.
Sıkça Sorulan Sorular
Hayır, @Published yalnızca ObservableObject'e uyan bir sınıfın içinde kullanılabilir. Yapılarda, yerel durum için @State veya iOS 17+'da @Observable makrosu ile @Bindable kullanın. Bir yapıda @Published kullanmaya çalışmak derleme hatasına neden olur.
Doğru yaklaşım: yeni değeri tamamen atayın (array = array + ["yeni"]). @Published referans değiştirmeyi izler, içerik değişikliğini değil. Referans türü koleksiyonları için, öğelerin iç durumunu değiştirdikten sonra manuel objectWillChange.send() kullanın.
@State, tek bir görünüm içindeki yerel durum için tasarlanmıştır ve yalnızca değer türleriyle çalışır. @Published, @ObservedObject veya @EnvironmentObject aracılığıyla birden çok görünüm tarafından okunabilen ObservableObject özellikleri içindir. @State daha basittir, @Published Combine entegrasyonu sayesinde daha güçlüdür.
Yalnızca değişiklikleri kullanıcı arayüzünü güncellemesi gerekenlerin ihtiyacı vardır. İç hesaplamalar, önbellekler veya geçici bayraklar için özellikler @Published gerektirmez — bu, gereksiz yeniden çizmeleri azaltır. @Published'i “bu özellik arayüz için önemlidir” sinyali olarak kullanın.
SwiftUI, NSManagedObject için @FetchRequest ve @ObservedObject aracılığıyla Core Data ile entegre olur. ManagedObject zaten ObservableObject'e uyar, bu nedenle @Published gerekli değildir — NSManagedObject değişiklikleri kendi başına bildirir. @Published, veri dönüşümü için Core Data ve UI arasındaki ViewModel katmanında kullanılır.
Özet
objectWillChange.send() çağırır, $property projeksiyonu aracılığıyla bir publisher oluştururassign(to: &$property), bir publisher'ın doğrudan bir @Published özelliğine abone olmasını sağlarAnahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun