@StateObject: এটি কী, ObservableObject তৈরি এবং পরিচালনা

লেখক: IT Sectr প্রকাশিত: 2026-06-26 পড়ার সময়: 9 মিনিট

@StateObject হল SwiftUI-এর একটি property wrapper যা একটি View-এর সম্পূর্ণ জীবনচক্র জুড়ে ObservableObject ইনস্ট্যান্স তৈরি করে এবং এর মালিকানা রাখে। যখন একটি View প্রথমবার স্ক্রিনে উপস্থিত হয়, @StateObject অবজেক্টটি ইনিশিয়ালাইজ করে এবং মেমরি থেকে View সরিয়ে না দেওয়া পর্যন্ত এটি সংরক্ষণ করে। এটি নিশ্চিত করে যে ইন্টারফেস পুনর্নির্মাণের সময় ডেটা রিসেট না হয় — উদাহরণস্বরূপ, থিম পরিবর্তন বা প্যারেন্ট View আপডেট করার সময়। Apple ডেভেলপার ডকুমেন্টেশন (2025) অনুসারে, @StateObject-কে SwiftUI শ্রেণিবিন্যাসে ObservableObject-এর জন্য প্রাথমিক সত্যের উৎস (source of truth) হিসাবে ব্যবহার করা উচিত, যখন চাইল্ড Views ইতিমধ্যে তৈরি করা অবজেক্টটি @ObservedObject বা @EnvironmentObject-এর মাধ্যমে গ্রহণ করে।

মূল পয়েন্ট

  • @StateObject — View-এর ভিতরে ObservableObject তৈরি এবং মালিকানার জন্য property wrapper।
  • একবার তৈরি — View-এর জীবনকালে অবজেক্টটি একবার ইনিশিয়ালাইজ হয় এবং পুনর্নির্মাণে পুনরায় তৈরি হয় না।
  • সত্যের উৎস — @ObservedObject-এর বিপরীতে, @StateObject শ্রেণিবিন্যাসে সত্যের উৎস।
  • জীবনচক্র — অবজেক্টটি ততক্ষণ বেঁচে থাকে যতক্ষণ View মেমরিতে বিদ্যমান, এবং এর সাথে ধ্বংস হয়।
  • ইনিশিয়ালাইজেশন — @StateObject-এর তৈরির সময় প্রাথমিক মান প্রয়োজন, সাধারণত প্যারামিটার সহ init-এর মাধ্যমে।

SwiftUI-এ @StateObject কী

@StateObject হল একটি property wrapper যা iOS 14-এ চালু করা হয়েছে, যা একটি View-কে ObservableObject প্রোটোকল অনুসরণকারী একটি ক্লাসের ইনস্ট্যান্স তৈরি এবং মালিকানা রাখতে দেয়। @State-এর বিপরীতে, যা মান টাইপের (structs) সাথে কাজ করে, @StateObject রেফারেন্স টাইপের জন্য ডিজাইন করা হয়েছে — ক্লাস যারা SwiftUI-কে তাদের বৈশিষ্ট্যের পরিবর্তন সম্পর্কে জানাতে পারে।

যখন একটি View @StateObject var viewModel: MyViewModel ব্যবহার করে, SwiftUI প্রথমবার View প্রদর্শিত হলে স্বয়ংক্রিয়ভাবে MyViewModel-এর একটি ইনস্ট্যান্স তৈরি করে এবং এটি একটি বিশেষ ফ্রেমওয়ার্ক স্টোরেজে সংরক্ষণ করে। প্রতিটি View আপডেটে (উদাহরণস্বরূপ, যখন প্যারেন্ট স্টেট পরিবর্তিত হয়), SwiftUI অবজেক্টটি পুনরায় তৈরি করে না — এটি View শ্রেণিবিন্যাস থেকে সরানো না হওয়া পর্যন্ত বিদ্যমান ইনস্ট্যান্সটি ব্যবহার করে।

Apple WWDC Session 10137 (2024) অনুসারে, @StateObject iOS 13-এ বিদ্যমান ডেটা হারানোর সমস্যার সমাধান করে যখন Views পুনর্নির্মিত হতো, যা ডেভেলপারদের প্যারেন্ট View-এ ObservableObject তৈরি করতে এবং ইনিশিয়ালাইজারের মাধ্যমে এটি পাস করতে বাধ্য করত। এর ফলে কোডের পুনরাবৃত্তি এবং দুর্ঘটনাবশত অবজেক্ট পুনরায় তৈরি হওয়ার ঝুঁকি ছিল।

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 কীভাবে কাজ করে

@StateObject প্রক্রিয়াটি SwiftUI-এর Combine ফ্রেমওয়ার্কের সাথে একীকরণের উপর ভিত্তি করে তৈরি। যখন একটি ObservableObject তার বৈশিষ্ট্যগুলিকে @Published অ্যাট্রিবিউট দিয়ে চিহ্নিত করে, SwiftUI স্বয়ংক্রিয়ভাবে ObservableObject প্রোটোকলে নির্মিত পাবলিশারের মাধ্যমে পরিবর্তনের সদস্যতা নেয়। যখন একটি প্রকাশিত বৈশিষ্ট্য পরিবর্তিত হয়, অবজেক্টটি objectWillChange পাবলিশারের মাধ্যমে সংকেত পাঠায়, যা এই অবজেক্টটি পর্যবেক্ষণ করা সমস্ত Views-এর পুনরায় অঙ্কন ট্রিগার করে।

SwiftUI ObservableObject ইনস্ট্যান্সটি একটি নির্দিষ্ট View ইনস্ট্যান্সের সাথে আবদ্ধ একটি বিশেষ স্টোরেজে সংরক্ষণ করে। এই স্টোরেজটি প্রথম রেন্ডারের সময় একবার তৈরি হয় এবং View ধ্বংস না হওয়া পর্যন্ত বিদ্যমান থাকে। এই কারণেই @StateObject রেফারেন্স স্থিতিশীলতার গ্যারান্টি দেয় — SwiftUI স্বয়ংক্রিয়ভাবে মেমরি পরিচালনা করে, View-এর ইনিশিয়ালাইজারের উপর নির্ভর না করে।

objc.io — Thinking in SwiftUI (2025) অনুসারে, @StateObject-এর অভ্যন্তরীণ বাস্তবায়ন @State-এর মতো একটি প্রক্রিয়া ব্যবহার করে তবে রেফারেন্স টাইপের জন্য: SwiftUI অবজেক্টের চারপাশে একটি বক্সিং র্যাপার তৈরি করে এবং তার নিজস্ব বরাদ্দকারীর মাধ্যমে এর জীবনচক্র পরিচালনা করে, যা ঘন ঘন View শ্রেণিবিন্যাস পুনর্নির্মাণের জন্য অপ্টিমাইজ করা।

@StateObject জীবনচক্র

  • তৈরি — যখন View প্রথমবার স্ক্রিনে উপস্থিত হয়, SwiftUI অবজেক্টের ইনিশিয়ালাইজার কল করে এবং রেফারেন্স সংরক্ষণ করে।
  • পুনর্নির্মাণ — যখন প্যারেন্ট View আপডেট হয়, অবজেক্টটি পুনরায় তৈরি হয় না; বিদ্যমান ইনস্ট্যান্স ব্যবহার করা হয়।
  • ধ্বংস — যখন View স্ক্রিন ছেড়ে শ্রেণিবিন্যাস থেকে সরানো হয়, SwiftUI অবজেক্টের deinit কল করে।

@StateObject বনাম @ObservedObject: মূল পার্থক্য

@StateObject এবং @ObservedObject-এর মধ্যে প্রধান পার্থক্য হল কে অবজেক্টের মালিক। @StateObject অবজেক্ট তৈরি করে এবং সংরক্ষণ করে — এটি মালিক। @ObservedObject শুধুমাত্র সেই অবজেক্টটি পর্যবেক্ষণ করে যা অন্য কোথাও তৈরি করা হয়েছে এবং ইনিশিয়ালাইজার বা বৈশিষ্ট্যের মাধ্যমে পাস করা হয়েছে।

বৈশিষ্ট্য@StateObject@ObservedObject
মালিকানাঅবজেক্ট তৈরি করে এবং মালিকশুধু পর্যবেক্ষণ করে
ইনিশিয়ালাইজেশনView-এর ভিতরে init/ডিফল্টের মাধ্যমেবাহ্যিক, প্যারামিটারের মাধ্যমে পাস
জীবনচক্রView-এর জীবনচক্রের সাথে আবদ্ধView দ্বারা নিয়ন্ত্রিত নয়
পুনর্নির্মাণআপডেটে পুনরায় তৈরি হয় নাবাহ্যিকভাবে প্রতিস্থাপিত হতে পারে
iOS সংস্করণiOS 14+iOS 13+

নিয়মটি সহজ: যদি View ObservableObject তৈরি করে — @StateObject ব্যবহার করুন। যদি View শুধুমাত্র প্যারেন্ট থেকে ইতিমধ্যে তৈরি অবজেক্ট গ্রহণ করে — @ObservedObject ব্যবহার করুন। এই নিয়ম লঙ্ঘন করলে ডেটা হারানো (যদি মালিকানার জন্য @ObservedObject ব্যবহার করা হয়) বা অতিরিক্ত অবজেক্ট তৈরি (যদি পর্যবেক্ষণের জন্য @StateObject ব্যবহার করা হয়) হতে পারে।

কখন @StateObject ব্যবহার করবেন

@StateObject সেই Views-এ ব্যবহার করা উচিত যা একটি নির্দিষ্ট ডেটা সেটের জন্য সত্যের উৎস। সাধারণ পরিস্থিতিতে নিজস্ব view model সহ স্ক্রিন, নেভিগেশন স্ট্যাকের রুট স্ক্রিন এবং নিজস্ব অবস্থা পরিচালনাকারী মোডাল উপস্থাপনা অন্তর্ভুক্ত।

  • View model সহ স্ক্রিন — প্রতিটি স্ক্রিন যা তার নিজস্ব ডেটা এবং যুক্তি পরিচালনা করে, @StateObject-এর মাধ্যমে তার view model তৈরি করা উচিত।
  • রুট View — NavigationStack বা TabView শ্রেণিবিন্যাসে, রুট উপাদান ডেটা তৈরি করে, এবং চাইল্ড উপাদানগুলি @ObservedObject-এর মাধ্যমে তা গ্রহণ করে।
  • মোডাল উইন্ডো — .sheet এবং .fullScreenCover-এর প্রায়ই ফর্ম বা প্রক্রিয়া পরিচালনার জন্য নিজস্ব @StateObject প্রয়োজন হয়।
  • সম্পাদনাযোগ্য তালিকা — তালিকার প্রতিটি সারি যাতে সম্পাদনা ফর্ম রয়েছে, তার নিজস্ব @StateObject থাকা উচিত।
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")
        }
    }
}

প্যারামিটার সহ @StateObject ইনিশিয়ালাইজ করা

@StateObject-কে প্যারামিটার সহ ইনিশিয়ালাইজ করতে বিশেষ সিনট্যাক্স প্রয়োজন, কারণ SwiftUI নিজেই অবজেক্ট তৈরি পরিচালনা করে। আপনি কেবল ইনিশিয়ালাইজারে প্যারামিটার পাস করতে পারবেন না — আপনাকে একটি এস্কেপিং ক্লোজার বা আলাদা ফ্যাক্টরি পদ্ধতি ব্যবহার করতে হবে।

Swift by Sundell (2024) অনুসারে, সবচেয়ে পরিষ্কার উপায় হল একটি ফ্যাক্টরি পদ্ধতি বা ক্লোজার ব্যবহার করা যা SwiftUI প্রথমবার অবজেক্ট তৈরি করার সময় কল করবে। একটি বিকল্প পদ্ধতি হল প্যারেন্ট View-এ ObservableObject ইনিশিয়ালাইজ করা এবং স্ট্যান্ডার্ড ইনিশিয়ালাইজার ব্যবহার করে @StateObject-এর মাধ্যমে এটি পাস করা।

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 সহ View ইনিশিয়ালাইজার-কে property wrapper-এ অ্যাক্সেসের জন্য বৈশিষ্ট্যের নামের আগে আন্ডারস্কোর (_viewModel) ব্যবহার করা উচিত, এর মান নয়। এটি ইনিশিয়ালাইজারগুলিতে property wrappers-এর সাথে কাজ করার জন্য একটি স্ট্যান্ডার্ড Swift প্যাটার্ন।

@StateObject-এর সাথে সাধারণ ভুল

সবচেয়ে সাধারণ ভুল হল যে View-এর অবজেক্টের মালিকানা থাকা উচিত, সেখানে @StateObject-এর পরিবর্তে @ObservedObject ব্যবহার করা। এই ক্ষেত্রে, প্রতিবার প্যারেন্ট পুনর্নির্মিত হলে, অবজেক্টটি পুনরায় তৈরি হবে, যা সমস্ত সঞ্চিত ডেটা হারানোর দিকে নিয়ে যাবে। এই ভুলটি NavigationStack বা TabView-এর সাথে জটিল শ্রেণিবিন্যাসে বিশেষভাবে ক্ষতিকর।

  • নেভিগেশনের সময় ডেটা হারানো — যদি একটি চাইল্ড স্ক্রিন তার নিজস্ব view model-এর জন্য @ObservedObject ব্যবহার করে, তাহলে পিছনে ফিরে গিয়ে পুনরায় খোলার সময় ডেটা রিসেট হবে।
  • মেমরি লিক — প্যারেন্ট View-এ @StateObject তৈরি করা যা কখনও সরানো হয় না, অবজেক্ট জমা হতে পারে যদি প্রতিটি চাইল্ড স্ক্রিনও নিয়ন্ত্রণ ছাড়া @StateObject তৈরি করে।
  • অবজেক্ট ডুপ্লিকেশন — একটি ObservableObject বিভিন্ন Views-এ একাধিক @StateObject-এ পাস করলে বেশ কয়েকটি স্বাধীন ইনস্ট্যান্স তৈরি হয় যা একে অপরের সাথে সিঙ্ক্রোনাইজ হয় না।

এই সমস্যাগুলি এড়াতে, একটি সহজ নিয়ম অনুসরণ করুন: প্রতি সত্য উৎসে একটি @StateObject। যদি ডেটা একাধিক স্ক্রিনে ভাগ করা উচিত — রুট View-তে একবার @StateObject তৈরি করুন এবং @ObservedObject বা @EnvironmentObject-এর মাধ্যমে চাইল্ড উপাদানগুলিতে পাস করুন।

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
}

সচরাচর জিজ্ঞাসিত প্রশ্ন

@StateObject এবং @State-এর মধ্যে পার্থক্য কী?

@State মান টাইপের (structs, স্ট্রিং, সংখ্যা) সাথে কাজ করে এবং মান সরাসরি SwiftUI স্টোরেজে সংরক্ষণ করে। @StateObject রেফারেন্স টাইপের — ObservableObject অনুসরণকারী ক্লাসগুলির সাথে কাজ করে। @State সহজ স্থানীয় অবস্থার জন্য উপযুক্ত, @StateObject যুক্তি এবং প্রকাশিত বৈশিষ্ট্য সহ জটিল অবজেক্টের জন্য।

আমি কি iOS 13-এ @StateObject ব্যবহার করতে পারি?

না, @StateObject শুধুমাত্র iOS 14 এবং তার উপরে উপলব্ধ। iOS 13-এর জন্য, @ObservedObject ব্যবহার করুন এবং ম্যানুয়াল জীবনচক্র পরিচালনার সাথে @State-এর মাধ্যমে প্যারেন্ট View-এ ObservableObject তৈরি করুন। একটি বিকল্প হল সেই ডেটার জন্য যা রেফারেন্স সেমান্টিক্স প্রয়োজন না, class-এর পরিবর্তে struct-এর সাথে @State ব্যবহার করা।

যদি আমি চাইল্ড View-এ @StateObject ব্যবহার করি যেখানে অবজেক্ট প্যারেন্ট থেকে পাস হয় তাহলে কী হবে?

চাইল্ড View ObservableObject-এর নিজস্ব কপি তৈরি করবে, যা প্যারেন্ট থেকে সম্পূর্ণ স্বাধীন। একটিতে পরিবর্তন অন্যটিকে প্রভাবিত করবে না। এটি প্রায় সবসময়ই একটি ভুল: প্যারেন্ট থেকে অবজেক্ট গ্রহণের জন্য @ObservedObject ব্যবহার করুন এবং View-এর ভিতরে নতুন অবজেক্ট তৈরির জন্য শুধুমাত্র @StateObject ব্যবহার করুন।

@StateObject-এর মাধ্যমে তৈরি অবজেক্ট কখন ধ্বংস হয়?

অবজেক্টটি ধ্বংস হয় যখন এটি তৈরি করা View সম্পূর্ণরূপে SwiftUI শ্রেণিবিন্যাস থেকে সরানো হয়। NavigationStack-এর একটি স্ক্রিনের জন্য, এটি নেভিগেশন স্ট্যাক থেকে পপ-এ ঘটে। মোডাল উইন্ডোর জন্য — যখন এটি বন্ধ করা হয়। TabView-এর জন্য — ট্যাব পরিবর্তন করার সময়, যদি View ক্যাশে না করা থাকে।

ইনিশিয়ালাইজেশনের সময় @StateObject-এ প্যারামিটার কীভাবে পাস করবেন?

আন্ডারস্কোরের মাধ্যমে property wrapper-এ অ্যাক্সেস সহ কাস্টম init ব্যবহার করুন: _viewModel = StateObject(wrappedValue: MyViewModel(param: value))। এই প্যাটার্নটি ObservableObject-এ যেকোনো প্যারামিটার পাস করার অনুমতি দেয়, পাশাপাশি View-এর জীবনকালে একবার অবজেক্ট তৈরির গ্যারান্টি বজায় রাখে।

সারসংক্ষেপ

  • @StateObject — View-এর ভিতরে ObservableObject তৈরি এবং মালিকানার জন্য property wrapper, iOS 14 থেকে উপলব্ধ।
  • একক তৈরি গ্যারান্টি — অবজেক্টটি একবার ইনিশিয়ালাইজ হয় এবং View পুনর্নির্মাণে পুনরায় তৈরি হয় না।
  • সত্যের উৎস — @StateObject সত্যের উৎস, যখন @ObservedObject শুধুমাত্র একজন পর্যবেক্ষক।
  • জীবনচক্র — অবজেক্টটি ততক্ষণ বেঁচে থাকে যতক্ষণ View SwiftUI শ্রেণিবিন্যাসে বিদ্যমান, এবং এটি ছাড়ার সময় ধ্বংস হয়।
  • প্যারামিটার সহ ইনিশিয়ালাইজেশন — _viewModel এবং StateObject(wrappedValue:) এর মাধ্যমে property wrapper-এ অ্যাক্সেস প্রয়োজন।
  • মালিকানা ভুল — অবজেক্ট তৈরির জন্য @ObservedObject ব্যবহার করলে পুনর্নির্মাণে ডেটা হারানো যায়।
  • এক অবজেক্ট — একটি @StateObject — ভাগ করা ডেটার জন্য, রুট View-এ @StateObject তৈরি করুন এবং @ObservedObject-এর মাধ্যমে চাইল্ডে পাস করুন।

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন