@StateObject: nedir, ObservableObject oluşturma ve yönetme

Yazar: IT Sectr Yayınlanma: 2026-06-26 Okuma süresi: 9 dk

@StateObject, SwiftUI'da bir View'in tüm yaşam döngüsü boyunca bir ObservableObject örneği oluşturan ve ona sahip olan bir property wrapper'dır. Bir View ilk kez ekranda göründüğünde, @StateObject nesneyi başlatır ve View bellekten kaldırılana kadar onu saklar. Bu, arayüz yeniden oluşturulduğunda (örneğin, tema değiştirirken veya üst View güncellenirken) verilerin sıfırlanmamasını sağlar. Apple Geliştirici Dokümantasyonu'na (2025) göre, @StateObject, SwiftUI hiyerarşisinde ObservableObject için birincil gerçek kaynağı (source of truth) olarak kullanılmalıdır, alt View'lar ise zaten oluşturulmuş nesneyi @ObservedObject veya @EnvironmentObject aracılığıyla alır.

Ana Noktalar

  • @StateObject — bir View içinde ObservableObject oluşturmak ve sahiplenmek için property wrapper.
  • Tek oluşturma — nesne, View'in ömrü boyunca bir kez başlatılır ve yeniden oluşturmalarda tekrar oluşturulmaz.
  • Gerçek kaynağı — @ObservedObject'in aksine, @StateObject hiyerarşideki gerçek kaynağıdır.
  • Yaşam döngüsü — nesne, View bellekte var olduğu sürece yaşar ve onunla birlikte yok edilir.
  • Başlatma — @StateObject, oluşturma sırasında genellikle parametreli init aracılığıyla bir başlangıç değeri gerektirir.

SwiftUI'da @StateObject Nedir

@StateObject, iOS 14'te tanıtılan bir property wrapper'dır ve bir View'in ObservableObject protokolüne uyan bir sınıfın örneğini oluşturmasına ve sahiplenmesine olanak tanır. Değer türleriyle (struct) çalışan @State'in aksine, @StateObject referans türleri — özelliklerindeki değişiklikleri SwiftUI'ya bildirebilen sınıflar — için tasarlanmıştır.

Bir View @StateObject var viewModel: MyViewModel kullandığında, SwiftUI View ilk kez görüntülendiğinde otomatik olarak bir MyViewModel örneği oluşturur ve bunu framework'ün özel bir deposunda saklar. Her View güncellemesinde (örneğin, üst durum değiştiğinde), SwiftUI nesneyi yeniden oluşturmaz — View hiyerarşiden kaldırılana kadar mevcut örneği kullanır.

Apple WWDC Session 10137 (2024)'ye göre, @StateObject, iOS 13'te View'lar yeniden oluşturulduğunda var olan veri kaybı sorununu çözer. Bu durum geliştiricileri üst View'da ObservableObject oluşturmaya ve bunu başlatıcı aracılığıyla iletmeye zorluyordu, bu da kod tekrarına ve yanlışlıkla nesnenin yeniden oluşturulması riskine yol açıyordu.

swift
import SwiftUI

class CounterViewModel: ObservableObject {
    @Published var count: Int = 0
    
    func increment() {
        count += 1
    }
}

struct CounterView: View {
    @StateObject var viewModel = CounterViewModel()
    
    var body: some View {
        VStack {
            Text("Count: \(viewModel.count)")
            Button("Increment", action: viewModel.increment)
        }
    }
}

@StateObject Nasıl Çalışır

@StateObject mekanizması, SwiftUI'nin Combine framework'ü ile entegrasyonuna dayanır. Bir ObservableObject, özelliklerini @Published niteliğiyle işaretlediğinde, SwiftUI otomatik olarak ObservableObject protokolüne yerleşik yayıncı aracılığıyla değişikliklere abone olur. Yayınlanan bir özellik değiştiğinde, nesne objectWillChange yayıncısı aracılığıyla bir sinyal gönderir ve bu nesneyi gözlemleyen tüm View'ların yeniden çizilmesini tetikler.

SwiftUI, ObservableObject örneğini belirli bir View örneğine bağlı özel bir depoda saklar. Bu depo, ilk render sırasında bir kez oluşturulur ve View yok edilene kadar varlığını sürdürür. Bu nedenle @StateObject referans kararlılığını garanti eder — SwiftUI, View'in başlatıcısına güvenmeden belleği otomatik olarak yönetir.

objc.io — Thinking in SwiftUI (2025)'ye göre, @StateObject'in iç uygulaması, @State'e benzer bir mekanizma kullanır ancak referans türleri için: SwiftUI, nesnenin etrafında bir sarma (boxing) oluşturur ve sık View hiyerarşisi yeniden oluşturmaları için optimize edilmiş kendi ayırıcısı aracılığıyla yaşam döngüsünü yönetir.

@StateObject Yaşam Döngüsü

  • Oluşturma — View ilk kez ekranda göründüğünde, SwiftUI nesnenin başlatıcısını çağırır ve referansı saklar.
  • Yeniden oluşturma — üst View güncellendiğinde, nesne yeniden oluşturulmaz; mevcut örnek kullanılır.
  • Yok etme — View ekrandan ayrılıp hiyerarşiden kaldırıldığında, SwiftUI nesnenin deinit'ini çağırır.

@StateObject vs @ObservedObject: Temel Farklar

@StateObject ve @ObservedObject arasındaki temel fark, nesneye kimin sahip olduğudur. @StateObject nesneyi oluşturur ve saklar — o sahiptir. @ObservedObject, başka bir yerde oluşturulan ve başlatıcı veya özellik aracılığıyla iletilen nesneyi yalnızca gözlemler.

Özellik@StateObject@ObservedObject
SahiplikNesneyi oluşturur ve sahiplenirSadece gözlemler
BaşlatmaView içinde init/varsayılan ileHarici, parametre ile iletilir
Yaşam döngüsüView'in yaşam döngüsüne bağlıView tarafından kontrol edilmez
Yeniden oluşturmaGüncellemede yeniden oluşturulmazHarici olarak değiştirilebilir
iOS sürümüiOS 14+iOS 13+

Kural basittir: View ObservableObject'i oluşturuyorsa — @StateObject kullanın. View yalnızca üstten zaten oluşturulmuş bir nesne alıyorsa — @ObservedObject kullanın. Bu kuralı ihlal etmek ya veri kaybına (sahiplik için @ObservedObject kullanılırsa) ya da aşırı nesne oluşturmaya (gözlem için @StateObject kullanılırsa) yol açar.

@StateObject Ne Zaman Kullanılır

@StateObject, belirli bir veri kümesi için gerçek kaynağı olan View'larda kullanılmalıdır. Tipik senaryolar arasında kendi view model'ine sahip ekranlar, navigasyon yığınlarının kök ekranları ve kendi durumunu yöneten modal sunumlar bulunur.

  • View model'li ekran — kendi verilerini ve mantığını yöneten her ekran, view model'ini @StateObject aracılığıyla oluşturmalıdır.
  • Kök View — NavigationStack veya TabView hiyerarşisinde, kök öğe verileri oluşturur ve alt öğeler bunları @ObservedObject aracılığıyla alır.
  • Modal pencereler — .sheet ve .fullScreenCover, bir formu veya süreci yönetmek için genellikle kendi @StateObject'ini gerektirir.
  • Düzenlenebilir liste — düzenleme formu içeren her liste satırı kendi @StateObject'ine sahip olmalıdır.
swift
struct ProfileView: View {
    @StateObject var viewModel = ProfileViewModel()
    
    var body: some View {
        NavigationStack {
            Form {
                TextField("Name", text: $viewModel.name)
                TextField("Email", text: $viewModel.email)
                Button("Save") {
                    viewModel.saveProfile()
                }
            }
            .navigationTitle("Profile")
        }
    }
}

Parametrelerle @StateObject Başlatma

@StateObject'i parametrelerle başlatmak özel bir sözdizimi gerektirir, çünkü SwiftUI nesne oluşturmayı kendisi yönetir. Başlatıcıya basitçe parametreler iletemezsiniz — bir kaçış closure'ı veya ayrı bir fabrika yöntemi kullanmanız gerekir.

Swift by Sundell (2024)'e göre, en temiz yaklaşım, SwiftUI'nin nesne ilk oluşturulduğunda çağıracağı bir fabrika yöntemi veya closure kullanmaktır. Alternatif bir yaklaşım, ObservableObject'i üst View'da başlatmak ve standart başlatıcıyı kullanarak @StateObject aracılığıyla iletmektir.

swift
class UserViewModel: ObservableObject {
    @Published var user: User
    
    init(user: User) {
        self.user = user
    }
}

struct UserDetailView: View {
    @StateObject var viewModel: UserViewModel
    
    init(user: User) {
        _viewModel = StateObject(wrappedValue: UserViewModel(user: user))
    }
    
    var body: some View {
        Text(viewModel.user.name)
    }
}

@StateObject ile View başlatıcısının, property wrapper'ın kendisine erişmek için özellik adından önce bir alt çizgi (_viewModel) kullanması gerektiğini unutmamak önemlidir. Bu, başlatıcılarda property wrapper'larla çalışmak için standart bir Swift modelidir.

@StateObject ile Sık Yapılan Hatalar

En yaygın hata, nesneye sahip olması gereken bir View için @StateObject yerine @ObservedObject kullanmaktır. Bu durumda, üst her yeniden oluşturulduğunda nesne yeniden oluşturulur ve birikmiş tüm verilerin kaybına yol açar. Bu hata, NavigationStack veya TabView ile karmaşık hiyerarşilerde özellikle sinsidir.

  • Navigasyon sırasında veri kaybı — bir alt ekran kendi view model'i için @ObservedObject kullanıyorsa, geri dönüp yeniden açıldığında veriler sıfırlanır.
  • Bellek sızıntısı — asla kaldırılmayan bir üst View'da @StateObject oluşturmak, her alt ekran da kontrolsüz bir şekilde @StateObject oluşturuyorsa nesne birikimine yol açabilir.
  • Nesne tekrarı — tek bir ObservableObject'i farklı View'lardaki birden çok @StateObject'e iletmek, birbiriyle senkronize olmayan birkaç bağımsız örnek oluşturur.

Bu sorunlardan kaçınmak için basit bir kural izleyin: gerçek kaynağı başına bir @StateObject. Veriler birden çok ekran arasında paylaşılacaksa — kök View'da bir kez @StateObject oluşturun ve @ObservedObject veya @EnvironmentObject aracılığıyla alt öğelere iletin.

swift
// ❌ Wrong: @ObservedObject for owning an object
struct BadView: View {
    @ObservedObject var vm = ViewModel() // will be recreated on each update!
}

// ✅ Correct: @StateObject for owning
struct GoodView: View {
    @StateObject var vm = ViewModel() // created once for View lifetime
}

Sıkça Sorulan Sorular

@StateObject ve @State arasındaki fark nedir?

@State değer türleriyle (struct, string, sayı) çalışır ve değeri doğrudan SwiftUI deposunda saklar. @StateObject referans türleriyle — ObservableObject'e uyan sınıflarla çalışır. @State basit yerel durumlar için uygundur, @StateObject mantık ve yayınlanmış özelliklere sahip karmaşık nesneler için uygundur.

iOS 13'te @StateObject kullanabilir miyim?

Hayır, @StateObject yalnızca iOS 14 ve üzerinde kullanılabilir. iOS 13 için @ObservedObject kullanın ve ObservableObject'i manuel yaşam döngüsü yönetimiyle @State aracılığıyla üst View'da oluşturun. Bir alternatif, referans semantiği gerektirmeyen veriler için class yerine struct ile @State kullanmaktır.

Nesnenin üstten iletildiği bir alt View'da @StateObject kullanırsam ne olur?

Alt View, üstten tamamen bağımsız olarak ObservableObject'in kendi kopyasını oluşturur. Birindeki değişiklikler diğerini etkilemez. Bu neredeyse her zaman bir hatadır: üstten nesne almak için @ObservedObject kullanın ve yalnızca View içinde yeni bir nesne oluşturmak için @StateObject kullanın.

@StateObject ile oluşturulan bir nesne ne zaman yok edilir?

Nesne, onu oluşturan View SwiftUI hiyerarşisinden tamamen kaldırıldığında yok edilir. NavigationStack'teki bir ekran için bu, navigasyon yığınından pop yapıldığında gerçekleşir. Modal bir pencere için — kapatıldığında. TabView için — View önbelleğe alınmamışsa, sekme değiştirildiğinde.

Başlatma sırasında @StateObject'e parametreleri nasıl iletirim?

Alt çizgi aracılığıyla property wrapper'a erişimi olan özel bir init kullanın: _viewModel = StateObject(wrappedValue: MyViewModel(param: value)). Bu model, View'in ömrü boyunca tek nesne oluşturma garantisini korurken ObservableObject'e herhangi bir parametre iletmeye olanak tanır.

Özet

  • @StateObject — bir View içinde ObservableObject oluşturmak ve sahiplenmek için property wrapper, iOS 14'ten itibaren kullanılabilir.
  • Tek oluşturma garantisi — nesne bir kez başlatılır ve View yeniden oluşturulduğunda tekrar oluşturulmaz.
  • Gerçek kaynağı — @StateObject gerçek kaynağıdır, @ObservedObject ise yalnızca bir gözlemcidir.
  • Yaşam döngüsü — nesne, View SwiftUI hiyerarşisinde var olduğu sürece yaşar ve ayrıldığında yok edilir.
  • Parametrelerle başlatma — _viewModel ve StateObject(wrappedValue:) aracılığıyla property wrapper'a erişim gerektirir.
  • Sahiplik hatası — nesne oluşturmak için @ObservedObject kullanmak yeniden oluşturmada veri kaybına yol açar.
  • Bir nesne — bir @StateObject — paylaşılan veriler için, kök View'da @StateObject oluşturun ve @ObservedObject aracılığıyla alt öğelere iletin.

Anahtar 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.

Projeyi tartış

Ayrıca okuyun