@StateObject: यह क्या है, @ObservedObject से अंतर और उदाहरण

लेखक: IT Sectr प्रकाशित: 2026-06-19 पढ़ने का समय: 7 मिनट

@StateObject SwiftUI में ObservableObject इंस्टेंस को सीधे view में बनाने और उसका स्वामित्व रखने के लिए एक Property Wrapper है। SwiftUI गारंटी देता है कि ऑब्जेक्ट व्यू के जीवनचक्र में एक बार इनिशियलाइज़ होता है और बार-बार रेंडर होने पर पुनः निर्मित नहीं होता। Apple Developer Documentation (2025) के अनुसार, @StateObject रूट व्यूज़ के लिए अनुशंसित है जो डेटा स्रोत बनाते हैं। @StateObject SwiftUI पदानुक्रम में ObservableObject के स्वामित्व के लिए सही विकल्प है।

मुख्य बातें

  • @StateObject — व्यू में ObservableObject बनाने और उसका स्वामित्व रखने के लिए Property Wrapper
  • एकल इंस्टेंस — ऑब्जेक्ट एक बार बनता है और रेंडर होने पर पुनः निर्मित नहीं होता
  • सत्य का स्रोत — @StateObject पूरे पदानुक्रम के लिए डेटा स्थिरता सुनिश्चित करता है
  • @ObservedObject से अंतर — @ObservedObject ऑब्जेक्ट का स्वामित्व नहीं रखता और उसे खो सकता है
  • रूट व्यू — @StateObject उस व्यू में उपयोग होता है जो ऑब्जेक्ट बनाता है

SwiftUI में @StateObject क्या है?

@StateObject एक Property Wrapper है जो SwiftUI 2.0 (iOS 14) में पेश किया गया, जो @ObservedObject और @State की क्षमताओं को जोड़ता है। @ObservedObject की तरह, यह ObservableObject में बदलावों की सदस्यता लेता है। @State की तरह, यह गारंटी देता है कि डेटा व्यू संरचना के बार-बार इनिशियलाइज़ेशन से बचा रहता है। @StateObject ऑब्जेक्ट को एक बार तब बनाता है जब व्यू पहली बार स्क्रीन पर आता है और इसे SwiftUI के हीप में संग्रहीत करता है।

@StateObject से पहले, डेवलपर्स सभी ObservableObjects के लिए @ObservedObject का उपयोग करते थे, जिनमें व्यू में बनाए गए ऑब्जेक्ट भी शामिल थे। इससे बार-बार डेटा हानि होती थी जब पैरेंट व्यू अपडेट होता था, जिससे व्यू संरचना पुनः निर्मित होती थी और @ObservedObject इंस्टेंस अपने साथ ले जाती थी। @StateObject ने स्थिरता गारंटी जोड़कर इस समस्या को हल किया।

मुख्य नियम: @StateObject उस व्यू में उपयोग होता है जो डिफ़ॉल्ट इनिशियलाइज़र (let model = ViewModel()) में ऑब्जेक्ट बनाता है। चाइल्ड व्यू जो यह ऑब्जेक्ट प्राप्त करते हैं, @ObservedObject का उपयोग करते हैं। यह पृथक्करण पूरे पदानुक्रम में सत्य का एकल स्रोत सुनिश्चित करता है।

@StateObject का जीवनचक्र

SwiftUI @StateObject के जीवनचक्र को @State के समान स्टोरेज मैनेजर के माध्यम से प्रबंधित करता है। जब व्यू पहली बार प्रकट होता है, SwiftUI ऑब्जेक्ट के लिए मेमोरी आवंटित करता है और इसे एक स्थायी क्षेत्र में संग्रहीत करता है। बाद के रेंडर (body कॉल) पर, ऑब्जेक्ट पुनः निर्मित नहीं होता—मौजूदा इंस्टेंस का उपयोग होता है। ऑब्जेक्ट तब तक जीवित रहता है जब तक व्यू पदानुक्रम में है।

जब व्यू पदानुक्रम से हटा दिया जाता है, SwiftUI @StateObject को नष्ट कर देता है, deinit को कॉल करता है। जब व्यू वापस पदानुक्रम में जोड़ा जाता है, तो एक नया इंस्टेंस बनाया जाता है। डिज़ाइन करते समय यह महत्वपूर्ण है: यदि आपको व्यू हटाने के बीच डेटा संरक्षित करने की आवश्यकता है, तो सेवा लेयर (सिंगलटन या DI) या @AppStorage का उपयोग करें।

swift
class TimerViewModel: ObservableObject {
    @Published var seconds: Int = 0
    private var timer: Timer?

    func start() {
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
            self.seconds += 1
        }
    }

    deinit {
        timer?.invalidate()
    }
}

struct TimerView: View {
    @StateObject var viewModel = TimerViewModel()

    var body: some View {
        Text("\(viewModel.seconds)s")
            .onAppear { viewModel.start() }
    }
}

उदाहरण में, TimerViewModel @StateObject के माध्यम से बनाया जाता है और तब तक जीवित रहता है जब तक TimerView स्क्रीन पर है। टाइमर onAppear में शुरू होता है और deinit में रुकता है। यदि @ObservedObject का उपयोग किया जाता, तो TimerView के प्रत्येक रेंडर पर seconds = 0 के साथ एक नया TimerViewModel बनता, और टाइमर कभी सही ढंग से काम नहीं करता। @StateObject गारंटी देता है कि viewModel अद्वितीय और स्थिर है।

@StateObject बनाम @ObservedObject: तुलना

@StateObject और @ObservedObject के बीच चुनाव इस पर निर्भर करता है कि ऑब्जेक्ट का मालिक कौन है। यदि व्यू ऑब्जेक्ट बनाता है—@StateObject। यदि व्यू को तैयार ऑब्जेक्ट मिलता है—@ObservedObject। यह नियम इतना महत्वपूर्ण है कि Xcode एक चेतावनी देता है जब @StateObject का उपयोग चाइल्ड व्यू में किया जाता है जो इनिशियलाइज़र के माध्यम से ऑब्जेक्ट प्राप्त करता है।

स्थितिअनुशंसित Wrapper
व्यू ViewModel() के माध्यम से मॉडल बनाता है@StateObject
व्यू मॉडल को पैरेंट से प्राप्त करता है@ObservedObject
मॉडल एक व्यू में उपयोग होता है@StateObject
मॉडल Environment के माध्यम से पास किया जाता है@EnvironmentObject
प्रीव्यू के लिए मॉडल आवश्यक है@ObservedObject + mock

व्यवहार में, परियोजना की शुरुआत में, @StateObject का उपयोग अक्सर रूट व्यू में और @ObservedObject का सभी चाइल्ड व्यू में किया जाता है। जैसे-जैसे एप्लिकेशन बढ़ता है, कुछ @StateObject इंस्टेंस को @EnvironmentObject से बदला जा सकता है। हालाँकि, @StateObject अपने स्वयं के तर्क वाली मॉड्यूलर स्क्रीन के लिए सबसे अच्छा विकल्प बना हुआ है।

@StateObject के उपयोग पैटर्न

पहला पैटर्न—@StateObject के साथ MVVM। ObservableObject के रूप में ViewModel @StateObject के माध्यम से व्यू में बनाया जाता है। ViewModel में @Published गुण और व्यावसायिक तर्क होते हैं। व्यू बदलावों की सदस्यता लेता है और इंटरफ़ेस अपडेट करता है। यह दृष्टिकोण परीक्षण योग्य अलगाव प्रदान करता है: ViewModel का सीधे इंस्टेंस बनाकर UI के बिना परीक्षण किया जा सकता है।

दूसरा पैटर्न—निर्भरताओं के साथ @StateObject। यदि ViewModel को सेवाओं की आवश्यकता है, तो पैरामीटर के साथ इनिशियलाइज़ेशन का उपयोग करें। उदाहरण के लिए, @StateObject var viewModel = UserViewModel(api: APIClient.shared)। हालाँकि, सावधान रहें: पैरामीटर प्रत्येक body रेंडर पर गणना किए जाते हैं, लेकिन ऑब्जेक्ट केवल एक बार बनता है। SwiftUI @StateObject के बाद के इनिशियलाइज़ेशन को अनदेखा करता है।

तीसरा पैटर्न—नेस्टेड @StateObject। SwiftUI में, एक व्यू में कई @StateObject हो सकते हैं, लेकिन यह शायद ही कभी उचित होता है। आमतौर पर एक @StateObject व्यू के संपूर्ण डेटा सेट को संभालता है। यदि तर्क बहुत जटिल हो जाता है, तो इसे एक @StateObject के अंदर @ObservedObject सेवाओं की संरचना में विभाजित करें।

swift
struct AppView: View {
    @StateObject var router = NavigationRouter()
    @StateObject var auth = AuthViewModel()

    var body: some View {
        ContentView()
            .environmentObject(router)
            .environmentObject(auth)
    }
}

उदाहरण में, AppView दो @StateObject बनाता है: NavigationRouter नेविगेशन प्रबंधन के लिए और AuthViewModel प्रमाणीकरण के लिए। दोनों ऑब्जेक्ट environmentObject के माध्यम से Environment में इंजेक्ट किए जाते हैं। कोई भी चाइल्ड व्यू इनिशियलाइज़र श्रृंखला से गुज़रे बिना @EnvironmentObject के माध्यम से उन तक पहुँच सकता है।

@StateObject और पैरामीटर के साथ इनिशियलाइज़ेशन

@StateObject किसी भी पैरामीटर के साथ इनिशियलाइज़ेशन का समर्थन करता है, लेकिन एक महत्वपूर्ण शर्त के साथ: इनिशियलाइज़र केवल एक बार कॉल होता है। बाद के body रेंडर पर, पैरामीटर में नए मान अनदेखा किए जाते हैं। इसका मतलब है कि यदि आप @State var id: Int = 5 को @StateObject var vm = ViewModel(id: id) में पास करते हैं, जब id बदलता है, ViewModel को नया मान नहीं मिलेगा।

इस समस्या को हल करने के लिए, सिंक्रनाइज़ेशन के लिए onReceive या onAppear का उपयोग करें। Combine के माध्यम से ViewModel के अंदर पैरामीटर बदलावों की सदस्यता लें या व्यू स्तर पर .onChange(of:) विधि के माध्यम से पैरामीटर पास करें। एक विकल्प @StateObject के बजाय @ObservedObject का उपयोग करना है यदि ऑब्जेक्ट को बाहरी बदलावों पर गतिशील रूप से प्रतिक्रिया देनी चाहिए।

swift
struct DetailView: View {
    let itemId: Int
    @StateObject var viewModel = DetailViewModel()

    var body: some View {
        Text(viewModel.title)
            .onAppear { viewModel.load(id: itemId) }
    }
}

सही दृष्टिकोण: DetailView itemId को let गुण के रूप में प्राप्त करता है (संरचना के इनिशियलाइज़र के माध्यम से पास किया गया), और @StateObject बिना पैरामीटर के DetailViewModel बनाता है। onAppear में, पास किए गए ID के लिए डेटा लोड करने हेतु load(id:) विधि कॉल की जाती है। यह सुनिश्चित करता है कि ViewModel @StateObject तंत्र द्वारा बनाया गया है, लेकिन डेटा वर्तमान ID के साथ प्रत्येक व्यू प्रकट होने पर लोड होता है।

@StateObject के साथ सामान्य गलतियाँ

मुख्य गलती—चाइल्ड व्यू में @StateObject का उपयोग करना जो पैरेंट से ऑब्जेक्ट प्राप्त करते हैं। यदि ParentView @StateObject model बनाता है, और ChildView @StateObject var model: ModelType (डिफ़ॉल्ट पैरामीटर के साथ) घोषित करता है, तो ChildView अपना स्वतंत्र इंस्टेंस बनाएगा। पैरेंट और चाइल्ड ऑब्जेक्ट आपस में जुड़े नहीं होंगे, और एक में बदलाव दूसरे में प्रतिबिंबित नहीं होंगे।

दूसरी गलती—List या ForEach में @StateObject रखना। सूची का प्रत्येक तत्व अपना स्वयं का @StateObject बनाता है, जिससे कई स्वतंत्र इंस्टेंस बनते हैं। सूचियों के लिए, सही दृष्टिकोण @ObservedObject के माध्यम से सभी तत्वों को एक ObservableObject पास करना या List के अंदर @State के साथ Identifiable संरचनाओं का उपयोग करना है।

तीसरी समस्या—deinit सफाई का अभाव। @StateObject पूरे व्यू जीवनचक्र के लिए जीवित रहता है। यदि ऑब्जेक्ट टाइमर, Combine सब्सक्रिप्शन या नेटवर्क अनुरोध बनाता है, तो deinit को उन्हें रद्द करना चाहिए। अन्यथा, मेमोरी लीक और स्क्रीन बंद होने के बाद पृष्ठभूमि कार्य जारी रहना अपरिहार्य है। हमेशा Combine Cancellable स्टोर का उपयोग करें या deinit में टाइमर को अमान्य करें।

अक्सर पूछे जाने वाले प्रश्न

SwiftUI में @StateObject कब पेश किया गया?

@StateObject को SwiftUI 2.0 में WWDC 2020 में iOS 14, macOS 11, watchOS 7 और tvOS 14 के साथ जोड़ा गया। इससे पहले, @ObservedObject ObservableObject के साथ काम करने का एकमात्र तरीका था, जिससे अक्सर डेटा हानि की समस्याएँ होती थीं।

क्या @StateObject वैकल्पिक हो सकता है?

नहीं, @StateObject Optional प्रकारों का समर्थन नहीं करता। ऑब्जेक्ट को घोषणा पर इनिशियलाइज़ किया जाना चाहिए। यदि आपको वैकल्पिक ऑब्जेक्ट की आवश्यकता है, तो वैकल्पिक प्रकार के साथ @ObservedObject या @EnvironmentObject का उपयोग करें।

कैसे जाँचें कि @StateObject केवल एक बार बना है?

ObservableObject के इनिशियलाइज़र और deinit में print(#function) जोड़ें। यदि रेंडर पर init कॉल नहीं होता—@StateObject सही ढंग से काम कर रहा है। यदि init हर बार कॉल होता है—@ObservedObject को @StateObject से बदलें।

क्या @StateObject का उपयोग UIKit के साथ UIHostingController के माध्यम से किया जा सकता है?

हाँ, @StateObject UIHostingController के माध्यम से UIKit में एम्बेडेड SwiftUI व्यू में काम करता है। ऑब्जेक्ट का जीवनचक्र SwiftUI व्यू से बंधा है, UIViewController से नहीं। यदि SwiftUI व्यू बदला जाता है, @StateObject नष्ट हो जाता है।

क्या बेहतर है: बड़े ViewModel वाला एक @StateObject या कई छोटे?

अलग-अलग जिम्मेदारियों वाले कई छोटे @StateObjects। यह परीक्षण क्षमता, पुन: उपयोग और प्रदर्शन में सुधार करता है—जब एक ऑब्जेक्ट बदलता है, तो इंटरफ़ेस के केवल सब्सक्राइब किए गए भाग पुनः चित्रित होते हैं, पूरा व्यू नहीं।

सारांश

  • @StateObject — व्यू में ObservableObject बनाने और उसका स्वामित्व रखने के लिए Property Wrapper
  • एकल इंस्टेंस — बाद के body रेंडर पर ऑब्जेक्ट पुनः निर्मित नहीं होता
  • सत्य का स्रोत — रूट व्यू में @StateObject पदानुक्रम के लिए डेटा स्थिरता सुनिश्चित करता है
  • चयन नियम — @StateObject निर्माण के लिए, @ObservedObject तैयार ऑब्जेक्ट प्राप्त करने के लिए
  • इनिशियलाइज़ेशन — @StateObject में पैरामीटर एक बार गणना किए जाते हैं, अपडेट ट्रैक नहीं किए जाते
  • Deinit — ObservableObject के deinit में टाइमर और सब्सक्रिप्शन की अनिवार्य सफाई
  • iOS 14+ — @StateObject iOS 14, macOS 11, watchOS 7, tvOS 14 से उपलब्ध

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें