@StateObject: apa itu, membuat dan mengelola ObservableObject

Penulis: IT Sectr Diterbitkan: 2026-06-26 Waktu membaca: 9 mnt

@StateObject adalah property wrapper di SwiftUI yang membuat dan memiliki instance ObservableObject sepanjang siklus hidup View. Ketika View pertama kali muncul di layar, @StateObject menginisialisasi objek dan menyimpannya hingga View dihapus dari memori. Ini menjamin bahwa data tidak akan direset saat pembangunan ulang antarmuka — misalnya, saat mengganti tema atau memperbarui View induk. Menurut Apple Developer Documentation (2025), @StateObject harus digunakan sebagai sumber kebenaran utama (source of truth) untuk ObservableObject dalam hierarki SwiftUI, sementara View anak menerima objek yang sudah dibuat melalui @ObservedObject atau @EnvironmentObject.

Poin Utama

  • @StateObject — property wrapper untuk membuat dan memiliki ObservableObject di dalam View.
  • Satu kali pembuatan — objek diinisialisasi satu kali selama masa hidup View dan tidak dibuat ulang saat pembangunan ulang.
  • Source of truth — @StateObject adalah sumber kebenaran dalam hierarki, berbeda dengan @ObservedObject.
  • Siklus hidup — objek hidup selama View ada di memori dan dihancurkan bersamanya.
  • Inisialisasi — @StateObject membutuhkan nilai awal saat pembuatan, biasanya melalui init dengan parameter.

Apa itu @StateObject di SwiftUI

@StateObject adalah property wrapper yang diperkenalkan di iOS 14 yang memungkinkan View untuk membuat dan memiliki instance dari kelas yang sesuai dengan protokol ObservableObject. Berbeda dengan @State yang bekerja dengan tipe nilai (struct), @StateObject ditujukan untuk tipe referensi — kelas yang dapat memberi tahu SwiftUI tentang perubahan properti mereka.

Ketika View menggunakan @StateObject var viewModel: MyViewModel, SwiftUI secara otomatis membuat instance MyViewModel saat pertama kali View ditampilkan dan menyimpannya di penyimpanan khusus framework. Pada setiap pembaruan View (misalnya, saat perubahan state induk), SwiftUI tidak membuat ulang objek — ia menggunakan instance yang sudah ada hingga View dihapus dari hierarki.

Menurut Apple WWDC Session 10137 (2024), @StateObject memecahkan masalah kehilangan data saat pembangunan ulang View yang ada di iOS 13, ketika pengembang harus membuat ObservableObject di View induk dan meneruskannya melalui inisialisator. Ini menyebabkan duplikasi kode dan risiko pembuatan ulang objek yang tidak disengaja.

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("Jumlah: \(viewModel.count)")
            Button("Tambah", action: viewModel.increment)
        }
    }
}

Bagaimana @StateObject bekerja

Mekanisme @StateObject didasarkan pada integrasi SwiftUI dengan framework Combine. Ketika ObservableObject menandai propertinya dengan atribut @Published, SwiftUI secara otomatis berlangganan perubahan melalui publisher yang tertanam dalam protokol ObservableObject. Saat properti yang dipublikasikan berubah, objek mengirim sinyal melalui publisher objectWillChange, yang memicu penggambaran ulang semua View yang mengamati objek ini.

SwiftUI menyimpan instance ObservableObject di penyimpanan khusus yang terikat pada instance View tertentu. Penyimpanan ini dibuat satu kali pada render pertama dan ada hingga penghancuran View. Inilah mengapa @StateObject menjamin stabilitas referensi ke objek — SwiftUI mengelola memori secara otomatis, tanpa bergantung pada inisialisator View.

Menurut objc.io — Thinking in SwiftUI (2025), implementasi internal @StateObject menggunakan mekanisme yang mirip dengan @State, tetapi untuk tipe referensi: SwiftUI membuat wrapper boxing di sekitar objek dan mengelola siklus hidupnya melalui alokator sendiri, yang dioptimalkan untuk pembangunan ulang hierarki View yang sering.

Siklus hidup @StateObject

  • Pembuatan — saat View pertama kali muncul di layar, SwiftUI memanggil inisialisator objek dan menyimpan referensi.
  • Pembangunan ulang — saat View induk diperbarui, objek tidak dibuat ulang, instance yang ada digunakan.
  • Penghancuran — ketika View meninggalkan layar dan dihapus dari hierarki, SwiftUI memanggil deinit objek.

@StateObject vs @ObservedObject: perbedaan utama

Perbedaan utama antara @StateObject dan @ObservedObject terletak pada siapa yang memiliki objek. @StateObject membuat dan menyimpan objek — ia adalah pemilik. @ObservedObject hanya mengamati objek yang dibuat di tempat lain dan diteruskan melalui inisialisator atau properti.

Karakteristik@StateObject@ObservedObject
KepemilikanMembuat dan memiliki objekHanya mengamati
InisialisasiDi dalam View melalui init/defaultDari luar, diteruskan melalui parameter
Siklus hidupTerikat pada siklus hidup ViewTidak dikendalikan oleh View
Pembuatan ulangTidak dibuat ulang saat pembaruanDapat diganti dari luar
Versi iOSiOS 14+iOS 13+

Aturannya sederhana: jika View membuat ObservableObject — gunakan @StateObject. Jika View hanya menerima objek yang sudah jadi dari induk — gunakan @ObservedObject. Pelanggaran aturan ini menyebabkan baik kehilangan data (jika menggunakan @ObservedObject untuk kepemilikan) atau pembuatan objek yang berlebihan (jika menggunakan @StateObject untuk pengamatan).

Kapan menggunakan @StateObject

@StateObject harus digunakan pada View yang menjadi sumber kebenaran untuk kumpulan data tertentu. Skenario umum termasuk layar dengan view model sendiri, layar root dari tumpukan navigasi, dan presentasi modal yang mengelola state sendiri.

  • Layar dengan view model — setiap layar yang mengelola data dan logikanya sendiri harus membuat view model melalui @StateObject.
  • View root — dalam hierarki NavigationStack atau TabView, elemen root membuat data, dan anak-anak menerimanya melalui @ObservedObject.
  • Jendela modal — .sheet dan .fullScreenCover sering memerlukan @StateObject sendiri untuk mengelola formulir atau proses.
  • Daftar dengan pengeditan — setiap baris daftar yang berisi formulir pengeditan harus memiliki @StateObject sendiri.
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("Simpan") {
                    viewModel.saveProfile()
                }
            }
            .navigationTitle("Profile")
        }
    }
}

Inisialisasi @StateObject dengan parameter

Inisialisasi @StateObject dengan parameter memerlukan sintaks khusus, karena SwiftUI mengelola pembuatan objek secara independen. Anda tidak bisa begitu saja meneruskan parameter ke inisialisator — Anda perlu menggunakan escaping closure atau metode pembuatan terpisah.

Menurut Swift by Sundell (2024), metode paling bersih adalah menggunakan metode pabrik atau closure yang akan dipanggil SwiftUI saat pertama kali membuat objek. Pendekatan alternatif — menginisialisasi ObservableObject di View induk dan meneruskannya melalui @StateObject menggunakan inisialisator standar.

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)
    }
}

Penting untuk diingat bahwa inisialisator View dengan @StateObject harus menggunakan garis bawah sebelum nama properti (_viewModel) untuk mengakses property wrapper itu sendiri, bukan nilainya. Ini adalah pola standar Swift untuk bekerja dengan property wrapper di inisialisator.

Kesalahan umum dengan @StateObject

Kesalahan paling umum adalah menggunakan @ObservedObject alih-alih @StateObject untuk View yang seharusnya memiliki objek. Dalam kasus ini, setiap kali induk dibangun ulang, objek akan dibuat ulang, yang menyebabkan hilangnya semua data yang terkumpul. Kesalahan ini sangat berbahaya dalam hierarki kompleks dengan NavigationStack atau TabView.

  • Kehilangan data saat navigasi — jika layar anak menggunakan @ObservedObject untuk view model sendiri, saat kembali dan membuka ulang, data akan direset.
  • Kebocoran memori — membuat @StateObject di View induk yang tidak pernah dihapus dapat menyebabkan akumulasi objek, jika setiap layar anak juga membuat @StateObject tanpa kontrol.
  • Duplikasi objek — meneruskan satu ObservableObject ke beberapa @StateObject di View yang berbeda menciptakan beberapa instance independen yang tidak sinkron satu sama lain.

Untuk menghindari masalah ini, ikuti aturan sederhana: satu @StateObject per satu sumber kebenaran. Jika data harus dibagikan di beberapa layar — buat @StateObject sekali di View root dan teruskan melalui @ObservedObject atau @EnvironmentObject ke elemen anak.

swift
// ❌ Salah: @ObservedObject untuk memiliki objek
struct BadView: View {
    @ObservedObject var vm = ViewModel() // akan dibuat ulang pada setiap pembaruan!
}

// ✅ Benar: @StateObject untuk memiliki
struct GoodView: View {
    @StateObject var vm = ViewModel() // dibuat sekali untuk masa hidup View
}

Pertanyaan yang Sering Diajukan

Apa perbedaan antara @StateObject dan @State?

@State bekerja dengan tipe nilai (struct, string, angka) dan menyimpan nilai langsung di penyimpanan SwiftUI. @StateObject bekerja dengan tipe referensi — kelas yang sesuai dengan ObservableObject. @State cocok untuk state lokal sederhana, @StateObject untuk objek kompleks dengan logika dan properti yang dipublikasikan.

Bisakah @StateObject digunakan di iOS 13?

Tidak, @StateObject hanya tersedia mulai iOS 14 ke atas. Untuk iOS 13 gunakan @ObservedObject dan buat ObservableObject di View induk melalui @State dengan manajemen siklus hidup manual. Alternatif — gunakan @State dengan struct alih-alih class untuk data yang tidak memerlukan semantik referensi.

Apa yang terjadi jika saya menggunakan @StateObject di View anak yang objeknya diteruskan dari induk?

View anak akan membuat salinan sendiri dari ObservableObject, sepenuhnya independen dari induk. Perubahan di satu salinan tidak akan tercermin di salinan lain. Ini hampir selalu merupakan kesalahan: gunakan @ObservedObject untuk menerima objek dari induk dan @StateObject hanya untuk membuat objek baru di dalam View.

Kapan objek yang dibuat melalui @StateObject dihancurkan?

Objek dihancurkan ketika View yang membuatnya sepenuhnya dihapus dari hierarki SwiftUI. Untuk layar di NavigationStack, ini terjadi saat pop dari tumpukan navigasi. Untuk jendela modal — saat ditutup. Untuk TabView — saat mengganti tab, jika View tidak di-cache.

Bagaimana cara meneruskan parameter ke @StateObject saat inisialisasi?

Gunakan init khusus dengan akses ke property wrapper melalui garis bawah: _viewModel = StateObject(wrappedValue: MyViewModel(param: value)). Pola ini memungkinkan meneruskan parameter apa pun ke ObservableObject, sambil mempertahankan jaminan pembuatan objek satu kali selama masa hidup View.

Kesimpulan

  • @StateObject — property wrapper untuk membuat dan memiliki ObservableObject di dalam View, tersedia mulai iOS 14.
  • Jaminan pembuatan satu kali — objek diinisialisasi sekali dan tidak dibuat ulang saat pembangunan ulang View.
  • Source of truth — @StateObject adalah sumber kebenaran, @ObservedObject hanya pengamat.
  • Siklus hidup — objek hidup selama View ada di hierarki SwiftUI dan dihancurkan saat meninggalkannya.
  • Inisialisasi dengan parameter — memerlukan akses ke property wrapper melalui _viewModel dan StateObject(wrappedValue:).
  • Kesalahan kepemilikan — menggunakan @ObservedObject untuk membuat objek menyebabkan kehilangan data saat pembangunan ulang.
  • Satu objek — satu @StateObject — untuk data bersama, buat @StateObject di View root dan teruskan ke anak melalui @ObservedObject.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga