@StateObject SwiftUI میں ایک property wrapper ہے جو View کی پوری زندگی کے دوران ObservableObject کی ایک مثال بناتا اور اس کا مالک ہوتا ہے۔ جب View پہلی بار اسکرین پر ظاہر ہوتی ہے، @StateObject آبجیکٹ کو ابتدائیہ دیتا ہے اور اسے اس وقت تک ذخیرہ کرتا ہے جب تک View میموری سے ہٹا نہیں دی جاتی۔ یہ یقینی بناتا ہے کہ انٹرفیس کی دوبارہ تعمیر پر ڈیٹا ری سیٹ نہ ہو — مثال کے طور پر، تھیم تبدیل کرنے یا والدین View کو اپ ڈیٹ کرنے پر۔ Apple ڈویلپر دستاویزات (2025) کے مطابق، @StateObject کو SwiftUI کے درجہ بندی میں ObservableObject کے لیے بنیادی ماخذ حقیقت (source of truth) کے طور پر استعمال کیا جانا چاہیے، جبکہ ذیلی Views @ObservedObject یا @EnvironmentObject کے ذریعے پہلے سے بنایا گیا آبجیکٹ وصول کرتی ہیں۔
اہم نکات
@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 بنانے اور اسے ابتدائیہ دینے والے کے ذریعے منتقل کرنے پر مجبور ہونا پڑتا تھا۔ اس سے کوڈ کی نقل اور غلطی سے آبجیکٹ کے دوبارہ بننے کا خطرہ تھا۔
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 کا طریقہ کار 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 اور @ObservedObject کے درمیان بنیادی فرق یہ ہے کہ آبجیکٹ کا مالک کون ہے۔ @StateObject آبجیکٹ بناتا اور محفوظ کرتا ہے — وہ مالک ہے۔ @ObservedObject صرف اس آبجیکٹ کو دیکھتا ہے جو کہیں اور بنایا گیا اور ابتدائیہ دینے والے یا خصوصیت کے ذریعے منتقل کیا گیا۔
| خصوصیت | @StateObject | @ObservedObject |
|---|---|---|
| ملکیت | آبجیکٹ بناتا اور اس کا مالک ہے | صرف دیکھتا ہے |
| ابتدائیہ | View کے اندر init/ڈیفالٹ کے ذریعے | بیرونی، پیرامیٹر کے ذریعے منتقل |
| زندگی کا چکر | View کے زندگی کے چکر سے منسلک | View کے ذریعے کنٹرول نہیں ہوتا |
| دوبارہ تخلیق | اپ ڈیٹ پر دوبارہ نہیں بنتا | بیرونی طور پر تبدیل کیا جا سکتا ہے |
| iOS ورژن | iOS 14+ | iOS 13+ |
قاعدہ آسان ہے: اگر View ObservableObject بناتی ہے — @StateObject استعمال کریں۔ اگر View صرف والدین سے پہلے سے بنا ہوا آبجیکٹ وصول کرتی ہے — @ObservedObject استعمال کریں۔ اس قاعدے کی خلاف ورزی یا تو ڈیٹا کے نقصان (اگر ملکیت کے لیے @ObservedObject استعمال کیا جائے) یا ضرورت سے زیادہ آبجیکٹ تخلیق (اگر مشاہدے کے لیے @StateObject استعمال کیا جائے) کا باعث بنتی ہے۔
@StateObject کو ان Views میں استعمال کیا جانا چاہیے جو ڈیٹا کے مخصوص سیٹ کے لیے ماخذ حقیقت ہیں۔ عام منظرناموں میں اپنے view model والی اسکرینیں، نیویگیشن اسٹیک کی جڑی اسکرینیں، اور موڈل پریزنٹیشنز شامل ہیں جو اپنی حالت خود منظم کرتی ہیں۔
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 کو پیرامیٹرز کے ساتھ ابتدائیہ دینے کے لیے خاص نحو درکار ہے، کیونکہ SwiftUI آبجیکٹ کی تخلیق خود منظم کرتا ہے۔ آپ ابتدائیہ دینے والے میں صرف پیرامیٹرز منتقل نہیں کر سکتے — آپ کو ایک فرار ہونے والا closure یا علیحدہ فیکٹری طریقہ استعمال کرنا ہوگا۔
Swift by Sundell (2024) کے مطابق، سب سے صاف طریقہ فیکٹری طریقہ یا closure استعمال کرنا ہے جسے SwiftUI آبجیکٹ کی پہلی تخلیق پر کال کرے گا۔ ایک متبادل طریقہ ObservableObject کو والدین View میں ابتدائیہ دینا اور معیاری ابتدائیہ دینے والے کا استعمال کرتے ہوئے @StateObject کے ذریعے منتقل کرنا ہے۔
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 نمونہ ہے۔
سب سے عام غلطی اس View کے لیے جسے آبجیکٹ کا مالک ہونا چاہیے، @StateObject کے بجائے @ObservedObject استعمال کرنا ہے۔ اس صورت میں، ہر بار جب والدین دوبارہ تعمیر ہوتا ہے، آبجیکٹ دوبارہ بنایا جائے گا، جس سے تمام جمع شدہ ڈیٹا ضائع ہو جائے گا۔ یہ غلطی NavigationStack یا TabView کے ساتھ پیچیدہ درجہ بندیوں میں خاص طور پر خطرناک ہے۔
ان مسائل سے بچنے کے لیے، ایک سادہ قاعدہ پر عمل کریں: فی ماخذ حقیقت ایک @StateObject۔ اگر ڈیٹا کو متعدد اسکرینوں میں مشترکہ ہونا چاہیے — جڑ View میں ایک بار @StateObject بنائیں اور @ObservedObject یا @EnvironmentObject کے ذریعے ذیلی عناصر کو منتقل کریں۔
// ❌ 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
}
اکثر پوچھے گئے سوالات
@State قدر کی اقسام (structs، سٹرنگز، اعداد) کے ساتھ کام کرتا ہے اور قدر کو براہ راست SwiftUI ذخیرہ میں محفوظ کرتا ہے۔ @StateObject حوالہ جاتی اقسام — ObservableObject کی تعمیل کرنے والی کلاسوں کے ساتھ کام کرتا ہے۔ @State سادہ مقامی حالتوں کے لیے موزوں ہے، @StateObject منطق اور شائع شدہ خصوصیات والے پیچیدہ آبجیکٹ کے لیے۔
نہیں، @StateObject صرف iOS 14 اور اس سے اوپر دستیاب ہے۔ iOS 13 کے لیے، @ObservedObject استعمال کریں اور دستی زندگی کے چکر کے انتظام کے ساتھ @State کے ذریعے والدین View میں ObservableObject بنائیں۔ ایک متبادل ان ڈیٹا کے لیے جو حوالہ جاتی معنویات کی ضرورت نہیں رکھتے، class کی بجائے struct کے ساتھ @State استعمال کرنا ہے۔
ذیلی View ObservableObject کی اپنی کاپی بنائے گی، جو والدین سے مکمل طور پر آزاد ہوگی۔ ایک میں تبدیلیاں دوسرے کو متاثر نہیں کریں گی۔ یہ تقریباً ہمیشہ ایک غلطی ہے: والدین سے آبجیکٹ وصول کرنے کے لیے @ObservedObject استعمال کریں اور View کے اندر نیا آبجیکٹ بنانے کے لیے صرف @StateObject استعمال کریں۔
آبجیکٹ اس وقت تباہ ہوتا ہے جب اسے بنانے والی View مکمل طور پر SwiftUI درجہ بندی سے ہٹا دی جاتی ہے۔ NavigationStack میں اسکرین کے لیے، یہ نیویگیشن اسٹیک سے پاپ ہونے پر ہوتا ہے۔ موڈل ونڈو کے لیے — جب اسے بند کیا جاتا ہے۔ TabView کے لیے — ٹیب تبدیل کرنے پر، اگر View کیش نہ کی گئی ہو۔
زیرخط کے ذریعے property wrapper تک رسائی کے ساتھ ایک حسب ضرورت init استعمال کریں: _viewModel = StateObject(wrappedValue: MyViewModel(param: value))۔ یہ نمونہ View کی زندگی میں ایک بار آبجیکٹ بنانے کی ضمانت برقرار رکھتے ہوئے ObservableObject میں کوئی بھی پیرامیٹر منتقل کرنے کی اجازت دیتا ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں