Observer — ایک رویاتی پیٹرن جس میں ایک شے (ناشر) متعدد سبسکرائبرز کو اپنی حالت میں تبدیلیوں کے بارے میں مطلع کرتی ہے۔ موبائل ڈویلپمنٹ میں، Observer ردعمل میکانزم کی بنیاد ہے: UI ڈیٹا کی تبدیلیوں کو سبسکرائب کرتا ہے اور خود بخود اپ ڈیٹ ہو جاتا ہے۔ یہ پیٹرن iOS میں NotificationCenter اور Android میں LiveData/Flow میں نافذ کیا گیا ہے۔ مزید تفصیلات Refactoring Guru: Observer پر دیکھیں۔
اہم نکات
Observer — ایک GoF رویاتی پیٹرن جو اشیاء کے درمیان ایک سے کئی کا انحصار متعین کرتا ہے۔ جب ایک شے (Subject یا Observable) اپنی حالت بدلتی ہے، تو تمام منحصر اشیاء (Observers) خود بخود مطلع اور اپ ڈیٹ ہو جاتی ہیں۔ پیٹرن کمزور جوڑے کو نافذ کرتا ہے: ناشر سبسکرائبرز کے مخصوص کلاسز کو نہیں جانتا — صرف یہ کہ وہ Observer انٹرفیس کو نافذ کرتے ہیں۔
Observer ساخت میں attach()، detach()، notify() طریقوں کے ساتھ Subject انٹرفیس اور update() طریقے کے ساتھ Observer انٹرفیس شامل ہے۔ ConcreteSubject حالت اور سبسکرائبرز کی فہرست ذخیرہ کرتا ہے۔ ConcreteObserver update() کو نافذ کرتا ہے اور تبدیلیوں پر ردعمل ظاہر کرتا ہے۔ موبائل ڈویلپمنٹ میں، GoF کا کلاسک نفاذ نایاب ہے — اسے بلٹ ان میکانزم سے بدل دیا جاتا ہے: NotificationCenter، Combine، Flow، LiveData، جو جدید APIs کے ساتھ ایک ہی خیال کو نافذ کرتے ہیں۔
Push vs Pull ماڈل — Push ماڈل میں، Subject تمام سبسکرائبرز کو ڈیٹا بھیجتا ہے (NotificationCenter.post)۔ Pull ماڈل میں، Subject صرف مطلع کرتا ہے، اور سبسکرائبر خود ڈیٹا کی درخواست کرتا ہے۔ Android LiveData Push استعمال کرتا ہے (ڈیٹا observe() میں پاس کیا جاتا ہے)، RxJava/Flow دونوں ماڈلز کو سپورٹ کرتے ہیں۔ انتخاب کام پر منحصر ہے: Push UI اپ ڈیٹس کے لیے آسان ہے، Pull ڈیٹا کی بڑی مقداروں کے لیے زیادہ موثر ہے جو سبسکرائبر حاصل نہیں کرنا چاہتا۔
NotificationCenter — Observer کو نافذ کرنے کے لیے iOS/macOS میں ایک بلٹ ان میکانزم۔ ناشر NotificationCenter.default.post(name:, object:, userInfo:) کے ذریعے Notification بھیجتا ہے۔ سبسکرائبر addObserver(forName:, queue:, using:) کے ذریعے رجسٹر ہوتا ہے۔ NotificationCenter نامی اطلاعوں (Notification.Name) کو سپورٹ کرتا ہے اور userInfo میں کوئی بھی ڈیٹا پاس کر سکتا ہے۔ UIKeyboardWillShowNotification، UIApplicationDidEnterBackgroundNotification — سسٹم مثالیں۔
extension Notification.Name {
static let userDidLogin = Notification.Name("userDidLogin")
}
// ناشر
NotificationCenter.default.post(
name: .userDidLogin,
object: nil,
userInfo: ["userId": "123"]
)
// سبسکرائبر
class ProfileViewModel {
private var observers: [NSObjectProtocol] = []
func startObserving() {
let observer = NotificationCenter.default.addObserver(
forName: .userDidLogin,
object: nil,
queue: .main
) { [weak self] notification in
guard let userId = notification.userInfo?["userId"] as? String else { return }
// سبسکرائبر واقعے پر ردعمل ظاہر کرتا ہے
self?.loadProfile(userId: userId)
}
observers.append(observer)
}
func stopObserving() {
observers.forEach { NotificationCenter.default.removeObserver($0) }
observers.removeAll()
}
}
Combine فریم ورک — iOS 13 میں متعارف کرایا گیا، NotificationCenter کا ایک جدید ردعمل متبادل۔ Publisher (NotificationCenter، URLSession، Timer) — ناشر، Subscriber (sink، assign) — سبسکرائبر۔ Combine ڈیٹا سٹریم کی تبدیلی کے لیے آپریٹرز (map، filter، combineLatest) شامل کرتا ہے۔ @Published — ایک پراپرٹی ریپر جو خود بخود سبسکرائبرز کو تبدیلیوں کے بارے میں مطلع کرتا ہے۔ SwiftUI کے ساتھ MVVM میں، Combine ViewModel اور View کو جوڑنے کے لیے NotificationCenter کی جگہ لیتا ہے۔
KVO (Key-Value Observing) — اشیاء کی انفرادی خصوصیات کو دیکھنے کے لیے ایک پرانا ObjC/Swift میکانزم۔ @objc dynamic var name: String — ایک قابل مشاہدہ خصوصیت۔ observe(.name) — سبسکرپشن۔ KVO صرف @objc-مطابق کلاسز اور ObjC وراثت کے ساتھ کام کرتا ہے۔ Apple نئے پروجیکٹس میں KVO کے بجائے Combine اور @Published کی تجویز کرتا ہے۔ KVO ہائبرڈ پروجیکٹس میں UIKit مطابقت کے لیے اہم رہتا ہے۔
LiveData — Observer کو نافذ کرنے کے لیے Android Architecture Components کا ایک جزو۔ ایک قابل مشاہدہ کلاس جو سبسکرائبرز کو ڈیٹا کی تبدیلیوں کے بارے میں مطلع کرتی ہے۔ LiveData لائف سائیکل سے آگاہ ہے: سبسکرائبرز (LifecycleOwner) تباہ ہونے پر خود بخود سبسکرپشن منسوخ کر دیتے ہیں۔ LiveData Push ماڈل استعمال کرتا ہے (ڈیٹا observe() میں پاس کیا جاتا ہے)۔ LiveData Jetpack Compose سے پہلے Android میں MVVM کا بنیادی بلاک ہے۔
// ViewModel — ناشر
class UserViewModel : ViewModel() {
private val _user = MutableLiveData<User?>(null)
val user: LiveData<User?> = _user
fun loadUser(id: String) {
viewModelScope.launch {
val result = userRepository.getUser(id)
_user.value = result
}
}
}
// Fragment — سبسکرائبر
class UserFragment : Fragment() {
private val viewModel: UserViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.user.observe(viewLifecycleOwner) { user ->
// سبسکرائبر تبدیلیوں پر ردعمل ظاہر کرتا ہے
userName.text = user?.name
userEmail.text = user?.email
}
}
}
StateFlow اور SharedFlow — Kotlin Coroutines کے ردعمل کی اقسام جنہوں نے Jetpack Compose میں LiveData کی جگہ لے لی۔ StateFlow — ایک مقررہ موجودہ قیمت کے ساتھ قابل مشاہدہ حالت رکھنے والا۔ SharedFlow — حالت کے بغیر ایک قابل ترتیب ہاٹ فلو، ایک بار کے واقعات (نیویگیشن، ٹوسٹ) کے لیے موزوں۔ دونوں اقسام Compose کے ساتھ مضبوطی سے مربوط ہیں: collectAsState()، collectAsEffect()۔ Compose کے ساتھ جدید Android پروجیکٹس میں StateFlow لازمی ہے۔
LiveData بمقابلہ StateFlow — LiveData Android لائف سائیکل سے منسلک ہے، StateFlow پلیٹ فارم سے آزاد ہے۔ StateFlow coroutines، آپریٹرز (map، filter) کو سپورٹ کرتا ہے اور Android انحصار کے بغیر جانچا جا سکتا ہے۔ LiveData Java مطابقت کے لیے آسان ہے۔ Google Kotlin + Compose کے ساتھ نئے پروجیکٹس کے لیے StateFlow اور پرانے پروجیکٹس یا Java کوڈ کی دیکھ بھال کے لیے LiveData تجویز کرتا ہے۔
میموری لیک — مناسب سبسکرپشن انتظام کے بغیر Observer کا بنیادی مسئلہ۔ اگر کوئی سبسکرائبر (Activity، Fragment، UIViewController) تباہ ہو جائے لیکن سبسکرپشن منسوخ نہ کی جائے، تو ناشر اس کا حوالہ رکھتا ہے اور کوڑا کرکٹ جمع کرنے والا میموری آزاد نہیں کر سکتا۔ Android میں، LifecycleOwner (Activity/Fragment) کو removeObserver() کال کرنا چاہیے یا observe(viewLifecycleOwner) استعمال کرنا چاہیے۔ iOS میں — deinit میں removeObserver یا Combine میں disposeBag۔
| پلیٹ فارم | Observer میکانزم | خودکار سبسکرپشن منسوخی | دستی سبسکرپشن منسوخی |
|---|---|---|---|
| iOS | NotificationCenter | نہیں | deinit میں removeObserver() |
| iOS | Combine (sink) | نہیں | store(in: &bag) — DisposeBag |
| iOS | KVO | نہیں | deinit میں removeObserver() |
| Android | LiveData | ہاں (LifecycleOwner) | removeObserver() اختیاری |
| Android | StateFlow | viewModelScope کے ذریعے | منسوخی پر cancel() Job |
| Android | RxJava | نہیں | CompositeDisposable میں dispose() |
سبسکرائبرز میں کمزور حوالہ — سبسکرپشن بلاکس میں closure استعمال کرتے وقت Swift میں [weak self] استعمال کریں اور Kotlin میں لائف سائیکل دائرہ کار کا حوالہ دیں۔ LiveData LifecycleOwner کے ذریعے سبسکرپشنز کا خود بخود انتظام کرتا ہے — سبسکرپشن صرف اس وقت فعال ہوتی ہے جب Lifecycle STARTED یا RESUMED حالت میں ہو۔ Compose میں StateFlow لائف سائیکل سے آگاہی کے ساتھ collectAsState() استعمال کرتا ہے۔ iOS میں NotificationCenter کو واضح [weak self] کی ضرورت ہوتی ہے کیونکہ closure self کا مضبوط حوالہ رکھتا ہے۔
Observer (GoF) اور ناشر-سبسکرائبر (PubSub) — ملتے جلتے لیکن مختلف پیٹرن۔ Observer میں، ناشر براہ راست سبسکرائبرز کو ان کے طریقے کال کر کے مطلع کرتا ہے۔ ناشر سبسکرائبرز کو جانتا ہے (ایک فہرست ذخیرہ کرتا ہے)۔ PubSub میں، ناشر اور سبسکرائبر ایک دوسرے کو نہیں جانتے — ان کے درمیان ایک ثالث (Event Bus، Message Queue، NotificationCenter) ہوتا ہے۔ ناشر ایک چینل پر پیغام بھیجتا ہے، سبسکرائبر چینل سنتا ہے۔ PubSub میں کمزور جوڑا ہے۔
موبائل ڈویلپمنٹ میں PubSub کی مثالیں — iOS میں NotificationCenter کو PubSub سمجھا جا سکتا ہے: ناشر سبسکرائبرز کو نہیں جانتا — وہ صرف ایک اطلاع پوسٹ کرتا ہے۔ Android میں EventBus یا Otto (متروک)۔ BroadcastChannel کے ساتھ SharedFlow — Kotlin دنیا میں PubSub۔ تقسیم شدہ نظاموں میں، PubSub RabbitMQ، Kafka، Google PubSub کے ذریعے نافذ کیا جاتا ہے۔ موبائل ڈویلپمنٹ کے لیے، PubSub ماڈیولر آرکیٹیکچر میں مفید ہے جہاں ماڈیولز کو ایک دوسرے پر منحصر نہیں ہونا چاہیے۔
کیا منتخب کریں — UI اپ ڈیٹس (ViewModel → View) کے لیے، Observer استعمال کریں (LiveData، StateFlow، @Published)۔ ماڈیولز کے درمیان واقعات (تصدیق، لاگ آؤٹ، تھیم تبدیل) کے لیے — PubSub (SharedFlow، NotificationCenter، EventBus)۔ Observer ایک اسکرین کے اندر آسان اور زیادہ موثر ہے، PubSub عالمی واقعات کے لیے زیادہ لچکدار ہے لیکن مضمر انحصار کی وجہ سے ڈیبگ کرنا مشکل ہے۔
اکثر پوچھے گئے سوالات
StateFlow Kotlin Coroutines کی ایک پلیٹ فارم سے آزاد قسم ہے، جبکہ LiveData Android لائف سائیکل سے منسلک ہے۔ StateFlow coroutines اور آپریٹرز کو سپورٹ کرتا ہے اور Android کے بغیر جانچا جا سکتا ہے۔ LiveData LifecycleOwner کے ذریعے سبسکرپشنز کا خود بخود انتظام کرتا ہے۔ Google Kotlin + Compose کے ساتھ نئے پروجیکٹس کے لیے StateFlow اور Java مطابقت کے لیے LiveData تجویز کرتا ہے۔
ہینڈلر closure میں [weak self] استعمال کریں اور deinit میں removeObserver() کال کریں۔ observer (NSObjectProtocol) کا حوالہ ذخیرہ کریں اور شے تباہ ہونے پر اسے ہٹا دیں۔ Combine میں، DisposeBag جاری ہونے پر خودکار سبسکرپشن منسوخی کے لیے AnyCancellable اور store(in:) استعمال کریں۔
ہاں، SwiftUI @Published اور @StateObject/@ObservedObject کے ساتھ ObservableObject کو سپورٹ کرتا ہے — یہ Observer کا بلٹ ان نفاذ ہے۔ @Published خود بخود View کو تبدیلیوں کے بارے میں مطلع کرتا ہے۔ Combine ضروری نہیں ہے: ObservableObject SwiftUI میں بلٹ ان objectWillChange Publisher استعمال کرتا ہے۔ Combine سٹریم کی تبدیلی کے لیے آپریٹرز شامل کرتا ہے۔
SharedFlow — ایک بار کے واقعات (نیویگیشن، ٹوسٹ، Snackbar) کے لیے جہاں موجودہ قیمت کی ضرورت نہیں ہے۔ StateFlow — UI حالت (ڈیٹا کی فہرست، لوڈنگ پیشرفت) کے لیے جہاں موجودہ سنیپ شاٹ کی ضرورت ہے۔ SharedFlow میں value خاصیت نہیں ہے اور یہ نئے سبسکرائبرز کو آخری قیمت واپس نہیں کرتا۔
KVO ایک پرانا ObjC میکانزم ہے، جس کے لیے @objc dynamic کی ضرورت ہے اور یہ صرف NSObject سے وراثت میں ملنے والی کلاسز کے ساتھ کام کرتا ہے۔ Combine ایک جدید Swift فریم ورک ہے، ٹائپ سیف، آپریٹرز اور SwiftUI انضمام کے ساتھ۔ Combine KVO اور NotificationCenter کی جگہ لے لیتا ہے۔ Apple نئے پروجیکٹس کے لیے Combine اور صرف پرانے سپورٹ کے لیے KVO تجویز کرتا ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں