SwiftUI ile uygulama geliştirirken, verilerinizi yönetmek için property wrapper'lar hayati bir rol oynar. Özellikle referans türlü nesnelerle çalışırken @StateObject ve @ObservedObject sıkça karıştırılır. Bu iki wrapper arasındaki farkı anlamak, uygulamanızın performansı ve doğruluğu için kritik öneme sahiptir. Peki, ne zaman @StateObject, ne zaman @ObservedObject kullanmalısınız?
Her iki wrapper da ObservableObject protokolüne uyan bir sınıfı izler ve bu sınıfta yayınlanan (published) özellikler değiştiğinde görünümün yenilenmesini sağlar. Fark, nesnenin sahipliği ve yaşam döngüsü yönetiminde ortaya çıkar.
@StateObject: Sahiplik ve Yaşam Döngüsü
@StateObject, bir ObservableObject örneğinin sahibi olduğunuzu belirtir. Bu wrapper, nesneyi oluşturan ve yöneten görünüme aittir. SwiftUI, bu nesneyi görünümün yaşam döngüsü boyunca (görünüm yeniden oluşturulsa bile) korur. İlk kez oluşturulan bir nesne için @StateObject kullanmalısınız. Örneğin:
class ViewModel: ObservableObject {
@Published var count = 0
}
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
Text("Count: \(viewModel.count)")
Button("Arttır") { viewModel.count += 1 }
}
}Önemli: @StateObject yalnızca bir nesnenin ilk kez oluşturulduğu yerde kullanılmalıdır. Aksi halde, beklenmedik davranışlarla karşılaşabilirsiniz.
@ObservedObject: Paylaşılan Nesneler İçin
@ObservedObject, bir ObservableObject örneğine başka bir kaynaktan (örneğin bir üst görünüm veya bir environment) eriştiğinizi belirtir. Bu wrapper, nesnenin sahibi değildir; yalnızca onu gözlemler. Nesne başka bir yerde oluşturulur ve bu görünüme dışarıdan iletilir. Örnek:
struct ChildView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
Text("Child: \(viewModel.count)")
}
}Burada ChildView, viewModel'i kendisi oluşturmaz; üst görünümden alır. Bu sayede aynı nesne birden fazla görünüm arasında paylaşılabilir ve istemci tarafı yönetimi basitleşir.
@StateObject vs @ObservedObject: Temel Farklar
| Özellik | @StateObject | @ObservedObject |
|---|---|---|
| Sahiplik | Evet, görünüme aittir | Hayır, dışarıdan gelir |
| Yaşam döngüsü | Görünümle birlikte yaşar, yeniden oluşturmalarda korunur | Dış kaynağın yaşam döngüsüne bağlıdır |
| Oluşturma | İlk değer ataması yapılır | Dışarıdan enjekte edilir |
| Kullanım yeri | Nesnenin ilk oluşturulduğu görünüm | Alt görünümler, paylaşılan veri |
Sık Yapılan Hatalar
- @StateObject'u alt görünümde kullanmak: Alt görünümde @StateObject ile yeni bir nesne oluşturmak, her görünüm yeniden oluşturulduğunda durumu sıfırlar. Bunun yerine @ObservedObject kullanın.
- @ObservedObject'in sahibini yanlış belirlemek: Eğer bir nesne birden fazla görünüm tarafından paylaşılacaksa, en üstteki ortak görünümde @StateObject olarak oluşturulmalı, alt görünümlerde @ObservedObject ile alınmalıdır.
- EnvironmentObject ile karıştırmak: @EnvironmentObject, gözlemleme açısından @ObservedObject'e benzer ancak dependency injection sağlar. Kalıtsal bir veri akışı için tercih edilir.
Doğru Kullanım Senaryoları
@StateObject Kullanılması Gereken Durumlar
- Bir görünümün kendine ait, başka hiçbir yerde paylaşılmayan bir durumu varsa (örneğin bir form ekranının view modeli).
- Nesnenin yalnızca bir kez oluşturulması ve görünümün yeniden oluşturulması durumunda bile korunması gerekiyorsa.
@ObservedObject Kullanılması Gereken Durumlar
- Bir üst görünümden alınan ve birden çok alt görünüm arasında paylaşılan bir durum söz konusuysa.
- Nesne zaten başka bir yerde (örneğin bir liste görünümünde) oluşturulmuşsa.
Örneğin, bir kullanıcı profil ekranında hesap bilgilerini yöneten bir AccountViewModel düşünün. Profil görünümünde @StateObject kullanarak bu view modeli oluşturur, ardından alt bileşenlerde (kullanıcı adı düzenleme, avatar değiştirme gibi) @ObservedObject ile aynı nesneye erişirsiniz. Bu sayede tüm alt görünümler aynı veri kaynağını gözlemler ve değişiklikler anında yansır.
Performans İpuçları
SwiftUI, @StateObject ve @ObservedObject ile işaretlenmiş nesnelerde yalnızca değişen özellikler için görünümü günceller. Ancak büyük ve karmaşık view modellerde, gereksiz yeniden çizimleri önlemek için equatable yapısını veya @Published alanlarını dikkatli seçin. Ayrıca, Android Jetpack Compose'da State Hoisting makalesinde olduğu gibi, platformlar arası state yönetimi prensiplerini anlamak size avantaj sağlar.
Uygulamanızda API çağrıları yapıyorsanız, hata durumlarını ve ağ isteği limitlerini yönetmek için REST API Rate Limiting konusunu inceleyebilir, kimlik doğrulama için ise JWT ile Güvenli Kimlik Doğrulama rehberimizden faydalanabilirsiniz.
Sonuç
@StateObject ve @ObservedObject arasındaki farkı anlamak, SwiftUI'da sağlam bir state yönetimi kurmanın temelidir. @StateObject, nesnenin sahibi olduğunuzda; @ObservedObject ise nesneyi başka bir yerden aldığınızda kullanılır. Doğru wrapper'ı seçmek, uygulamanızın öngörülebilir ve hatasız çalışmasını sağlar. Bu prensipleri projelerinize uygulayarak daha temiz ve sürdürülebilir kod yazabilirsiniz.
Sık Sorulan Sorular
@StateObject ve @ObservedObject arasındaki temel fark nedir?
@StateObject bir ObservableObject'in sahibi olduğunuzu ve onu oluşturduğunuzu belirtirken, @ObservedObject yalnızca dışarıdan alınan bir nesneyi gözlemler. @StateObject görünüm yeniden oluşturulduğunda korunur, @ObservedObject ise dış kaynağın yaşam döngüsüne bağlıdır.
Bir alt görünümde @StateObject kullanabilir miyim?
Genelde önerilmez. Alt görünümde @StateObject kullanırsanız, her seferinde yeni bir nesne oluşur ve durum kaybolur. Bunun yerine üst görünümde @StateObject ile oluşturulmuş nesneyi @ObservedObject ile alın.
@EnvironmentObject ile @ObservedObject arasındaki fark nedir?
@EnvironmentObject, dependency injection sağlar ve görünüm hiyerarşisinde yukarıdan aşağıya otomatik olarak iletilir. @ObservedObject ise açıkça bir parametre olarak geçirilir. İkisi de gözlemleme yapar, ancak @EnvironmentObject daha çok global veri için uygundur.
Birden fazla görünüm aynı veriyi paylaşacaksa hangi wrapper tercih edilmeli?
Veriyi en üst ortak görünümde @StateObject ile oluşturun, ardından alt görünümlerde @ObservedObject veya @EnvironmentObject kullanarak paylaşın.
@StateObject kullanırken nelere dikkat etmeliyim?
@StateObject'i yalnızca nesnenin ilk kez oluşturulduğu yerde kullanın. Görünümün yeniden oluşturulmasına rağmen nesne korunur ancak yanlışlıkla başka bir yerde tekrar @StateObject tanımlamak istenmeyen davranışlara yol açar.






