viewDidDisappear হল UIViewController-এর একটি জীবনচক্র পদ্ধতি যা iOS ডিভাইসের স্ক্রীন থেকে ভিউ সম্পূর্ণরূপে অদৃশ্য হওয়ার সাথে সাথেই কল করা হয়। ডেভেলপাররা এটি ব্যবহার করেন অ্যানিমেশন বন্ধ করতে, RAM মুক্ত করতে, বিজ্ঞপ্তি থেকে আনসাবস্ক্রাইব করতে এবং বর্তমান অবস্থা সংরক্ষণ করতে। Apple Developer Documentation (2025) অনুসারে, এই পদ্ধতির সঠিক বাস্তবায়ন সক্রিয় নেভিগেশন সহ অ্যাপ্লিকেশনগুলিতে 40% পর্যন্ত মেমরি লিক প্রতিরোধ করে। এটি ছাড়া, ব্যাকগ্রাউন্ড প্রক্রিয়াগুলি চলতে থাকতে পারে, ব্যাটারি এবং CPU রিসোর্স গ্রহণ করে। viewDidDisappear-এর সঠিক ব্যবহার iOS ডেভেলপারের একটি মূল দক্ষতা, যা সরাসরি অ্যাপ্লিকেশনের কর্মক্ষমতা এবং স্থিতিশীলতাকে প্রভাবিত করে।
মূল বিষয়
viewDidDisappear হল UIViewController সুপারক্লাসের একটি হুক পদ্ধতি যা সিস্টেম কল করে যখন ভিউ স্ক্রিনের উইন্ডো হায়ারার্কি থেকে সম্পূর্ণরূপে সরিয়ে ফেলা হয়। এটি UIKit-এ স্ট্যান্ডার্ড ভিউ জীবনচক্রের অংশ এবং ডেভেলপারকে সমাপ্তি কার্যক্রম সম্পাদনের জন্য একটি পয়েন্ট প্রদান করে।
পদ্ধতিটি UIViewController প্রোটোকলে ঘোষিত এবং সমস্ত সাবক্লাসে ওভাররাইড করার জন্য উপলব্ধ। পদ্ধতির সিগনেচার হল: override func viewDidDisappear(_ animated: Bool). প্যারামিটার animated নির্দেশ করে যে ট্রানজিশনটি অ্যানিমেশন সহ ছিল কিনা। এটি আরও সুনির্দিষ্ট আচরণ নিয়ন্ত্রণের জন্য প্রোগ্রামেটিক এবং অ্যানিমেটেড ট্রানজিশনের মধ্যে পার্থক্য করতে দেয়।
viewWillDisappear-এর বিপরীতে, যা অ্যানিমেশন শুরুর আগে কল করা হয়, viewDidDisappear গ্যারান্টি দেয় যে ভিউ আর ব্যবহারকারীর কাছে দৃশ্যমান নয়। এটি সেই অপারেশনগুলির জন্য গুরুত্বপূর্ণ যা শুধুমাত্র ইন্টারফেস সম্পূর্ণরূপে লুকানোর পরে কার্যকর করা উচিত — উদাহরণস্বরূপ, পূর্ণ-স্ক্রিন ওভারলে উপাদান লুকানো বা ভিডিও রেকর্ডিং শেষ করা।
পদ্ধতিটি বেস ক্লাস UIViewController-এ সংজ্ঞায়িত এবং নিম্নলিখিত সিগনেচার রয়েছে:
import UIKit
class MyViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// রিসোর্স মুক্ত ও আনসাবস্ক্রাইব
}
}
বাস্তবায়নের প্রথম লাইনে super.viewDidDisappear(animated)-এর বাধ্যতামূলক কল UIKit-এর একটি প্রয়োজনীয়তা। এটি ছাড়া, সুপারক্লাস ভিউ প্রদর্শনের সাথে সম্পর্কিত অভ্যন্তরীণ প্রক্রিয়াগুলি সঠিকভাবে সম্পূর্ণ করতে পারে না। এই নিয়ম উপেক্ষা করলে অপ্রত্যাশিত নেভিগেশন আচরণ এবং সম্ভাব্য ক্র্যাশ হয়।
সম্পূর্ণ UIViewController জীবনচক্র ছয়টি মূল পদ্ধতি নিয়ে গঠিত, প্রতিটি ভিউ অস্তিত্বের একটি নির্দিষ্ট পর্যায়ের জন্য দায়ী। viewDidDisappear viewWillDisappear-কে অনুসরণ করে, অদৃশ্য হওয়ার ক্রমটি সম্পূর্ণ করে। রিসোর্স বরাদ্দ এবং মুক্তি সঠিকভাবে বিতরণ করতে সমস্ত পদ্ধতির কল ক্রম বোঝা গুরুত্বপূর্ণ।
ভিউ প্রদর্শিত হলে ক্রম: viewDidLoad → viewWillAppear → viewDidAppear। লুকানোর সময়: viewWillDisappear → viewDidDisappear। চূড়ান্ত পর্যায় — deinit, যা UIViewController অবজেক্ট ধ্বংস হলে কল করা হয়। এই ছয়টি পদ্ধতি একটি সম্পূর্ণ চক্র গঠন করে যা পূর্বানুমানযোগ্য অবস্থা ব্যবস্থাপনা নিশ্চিত করে।
| পদ্ধতি | কলের মুহূর্ত | সাধারণ ব্যবহার |
|---|---|---|
| viewDidLoad | মেমরিতে ভিউ লোড হওয়ার পরে | প্রাথমিক UI সেটআপ, ডেটাতে সাবস্ক্রাইব |
| viewWillAppear | স্ক্রিনে ভিউ প্রদর্শিত হওয়ার আগে | প্রদর্শনের আগে ডেটা আপডেট করা |
| viewDidAppear | স্ক্রিনে ভিউ প্রদর্শিত হওয়ার পরে | অ্যানিমেশন শুরু করা, পর্যবেক্ষণ শুরু করা |
| viewWillDisappear | ভিউ অদৃশ্য হওয়ার আগে | ইনপুট ডেটা সংরক্ষণ, অপারেশন বাতিল করা |
| viewDidDisappear | ভিউ অদৃশ্য হওয়ার পরে | রিসোর্স মুক্ত করা, বিজ্ঞপ্তি থেকে আনসাবস্ক্রাইব |
| deinit | যখন অবজেক্ট ধ্বংস হয় | চূড়ান্ত পরিষ্কার, শক্তিশালী রেফারেন্স মুক্ত করা |
এই পদ্ধতিগুলির প্রতিটি সংশ্লিষ্ট ট্রানজিশনের জন্য ঠিক একবার কল করা হয়। ব্যতিক্রম হল viewDidLoad, যা আবার কল করা হতে পারে যদি রিসোর্স চাপের কারণে ViewController মেমরি থেকে আনলোড করা হয় এবং তারপর পুনরুদ্ধার করা হয়। এই ক্ষেত্রে, viewDidDisappear পুনরাবৃত্ত viewDidLoad-এর আগে হবে।
পদ্ধতি সিগনেচারে প্যারামিটার animated নির্দেশ করে যে ট্রানজিশনটি অ্যানিমেটেড ছিল কিনা। এটি অ্যানিমেশন ছাড়া প্রোগ্রামেটিক ট্রানজিশন (উদাহরণস্বরূপ, rootViewController সেট করার সময়) এবং ব্যবহারকারীর দ্বারা শুরু করা অ্যানিমেটেড ট্রানজিশনের মধ্যে পার্থক্য করতে কার্যকর। যদি মান false হয়, তাহলে সম্ভবত নিয়ন্ত্রকটি সিস্টেম দ্বারা জোর করে লুকানো হয়েছে — এই ক্ষেত্রে, কিছু সময়-নির্ভর অপারেশন অপ্রাসঙ্গিক হতে পারে।
সিস্টেম viewDidDisappear ঠিক দুটি পরিস্থিতিতে কল করে: যখন ViewController নেভিগেশন স্ট্যাক থেকে সরানো হয় এবং যখন এটি অন্য নিয়ন্ত্রক দ্বারা আচ্ছাদিত হয়। উভয় ক্ষেত্রেই, পদ্ধতিটি সংকেত দেয় যে ভিউ আর ব্যবহারকারীর কাছে দৃশ্যমান নয়, এবং ডেভেলপারের ব্যাকগ্রাউন্ডে প্রয়োজন নেই এমন রিসোর্স মুক্ত করা উচিত। এই পরিস্থিতিগুলি বোঝা অ্যাপ্লিকেশন অবস্থা সম্পর্কে ভুল ধারণা প্রতিরোধ করে।
প্রথম পরিস্থিতি — UINavigationController থেকে pop. যখন ব্যবহারকারী পিছনের বাটন চাপে, popViewController:animated কল করা হয়। বর্তমান নিয়ন্ত্রক viewDidDisappear পায়, এবং তারপর, যদি তার জন্য আর কোনও শক্তিশালী রেফারেন্স না থাকে, deinit। দ্বিতীয় পরিস্থিতি — present/dismiss. যখন একটি নতুন নিয়ন্ত্রক মোডলি উপস্থাপিত হয়, presentingViewController viewDidDisappear পায়। ডিসমিস করার সময়, এই পদ্ধতিটি সেই নিয়ন্ত্রকের উপর কল করা হয় যা মোডলি উপস্থাপিত হয়েছিল।
তৃতীয়, কম স্পষ্ট পরিস্থিতি — child ViewController যোগ করা. যদি কন্টেইনার নিয়ন্ত্রকে (উদাহরণস্বরূপ, UIPageViewController বা UITabBarController) একটি নতুন চাইল্ড নিয়ন্ত্রক যোগ করা হয়, সক্রিয় চাইল্ড নিয়ন্ত্রক viewDidDisappear পায়। এটি ট্যাব বা পৃষ্ঠা ক্যারোসেল সহ অ্যাপ্লিকেশনগুলির জন্য গুরুত্বপূর্ণ — প্রতিটি ট্যাব সুইচ নিষ্ক্রিয় স্ক্রিনের কাজ সঠিকভাবে স্থগিত করা উচিত।
একটি গুরুত্বপূর্ণ ব্যতিক্রম আছে: যদি UIViewController একটি মোডাল উইন্ডোতে প্রদর্শিত হয় এবং ব্যবহারকারী নিচে সুইপ করে এটিকে ইন্টারঅ্যাকটিভভাবে বন্ধ করে, সিস্টেম অসম্পূর্ণ সুইপের জন্য viewDidDisappear কল নাও করতে পারে। এই আচরণ iOS 13-এ ইন্টারঅ্যাকটিভ ডিসমিসের সাথে দেখা দিয়েছে। ডেভেলপারদের ইভেন্ট প্রাপ্তির গ্যারান্টি দিতে UIAdaptivePresentationControllerDelegate এবং didDismiss পদ্ধতির মাধ্যমে অবস্থা পরিচালনা করা উচিত।
আরেকটি বৈশিষ্ট্য — মেমরি সতর্কতা. যখন মেমরি কম থাকে, সিস্টেম স্ক্রিনে দৃশ্যমান নয় এমন নিয়ন্ত্রকের ভিউ আনলোড করতে পারে। এই ক্ষেত্রে, viewDidDisappear সাধারণত আনলোড করার আগে কল করা হয়, কিন্তু ডেভেলপারের সুরক্ষা জাল হিসাবে didReceiveMemoryWarning-এ গুরুত্বপূর্ণ পরিষ্কার অপারেশনগুলি দ্বিগুণ করা উচিত। এই পদ্ধতি চরম পরিস্থিতিতে ডেটা ক্ষতি প্রতিরোধ করে।
viewDidDisappear তিনটি প্রধান শ্রেণীর অপারেশনের জন্য ব্যবহৃত হয়: কার্যকলাপ বন্ধ করা, রিসোর্স মুক্ত করা এবং অবস্থা সংরক্ষণ করা। প্রতিটি শ্রেণীর নিজস্ব সর্বোত্তম অনুশীলন রয়েছে যা iOS ডেভেলপার সম্প্রদায় দ্বারা বিকশিত হয়েছে। আসুন বাস্তবায়ন উদাহরণ সহ সবচেয়ে সাধারণ পরিস্থিতিগুলি দেখি।
একটি সাধারণ ভুল হল viewDidLoad-এ বিজ্ঞপ্তিতে সাবস্ক্রাইব করা এবং কখনও আনসাবস্ক্রাইব না করা। এটি একটি ডি-অ্যালোকেটেড অবজেক্টে হ্যান্ডলার কল হওয়ার কারণ হয়, যা ক্র্যাশের দিকে নিয়ে যায়। সঠিক পদ্ধতি হল viewWillAppear-এ সাবস্ক্রাইব করা এবং viewDidDisappear-এ আনসাবস্ক্রাইব করা, যা নিশ্চিত করে যে সাবস্ক্রিপশন শুধুমাত্র তখনই সক্রিয় যখন নিয়ন্ত্রক স্ক্রিনে প্রদর্শিত হয়।
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleKeyboardShow),
name: UIResponder.keyboardWillShowNotification,
object: nil
)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
এই প্যাটার্ন নিশ্চিত করে যে বিজ্ঞপ্তি হ্যান্ডলার শুধুমাত্র তখনই সক্রিয় যখন নিয়ন্ত্রক স্ক্রিনে দৃশ্যমান হয়। অন্য স্ক্রিনে নেভিগেট করার সময়, সমস্ত সাবস্ক্রিপশন স্বয়ংক্রিয়ভাবে সরানো হয় এবং ফিরে আসার সময় পুনরুদ্ধার করা হয়। এটি অ্যাপ্লিকেশনের নির্ভরযোগ্যতা বাড়ায় এবং বিজ্ঞপ্তি সম্পর্কিত বাগগুলির একটি শ্রেণী দূর করে।
আসুন বাস্তব প্রকল্পে viewDidDisappear ব্যবহারের দুটি ব্যবহারিক উদাহরণ পরীক্ষা করি। প্রথম উদাহরণটি স্ক্রিন লুকানো হলে টাইমার বন্ধ করার প্রদর্শন করে, দ্বিতীয়টি কীবোর্ড পর্যবেক্ষণ সঠিকভাবে শেষ করার দেখায়। উভয় উদাহরণ নিয়ন্ত্রক নিষ্ক্রিয় হলে রিসোর্স মুক্ত করার নীতি অনুসরণ করে।
যদি UI আপডেট করার জন্য স্ক্রিনে Timer চলছে (উদাহরণস্বরূপ, কাউন্টডাউন বা ক্যারোসেল), তবে নিয়ন্ত্রক লুকানো হলে এটি বন্ধ করা আবশ্যক। ব্যাকগ্রাউন্ডে টাইমার চালিয়ে যাওয়া শুধুমাত্র CPU রিসোর্স গ্রহণ করে না বরং অদৃশ্য UI আপডেট করার চেষ্টা করলে একটি ব্যতিক্রমও সৃষ্টি করতে পারে।
class CountdownViewController: UIViewController {
private var countdownTimer: Timer?
private var remainingSeconds: Int = 60
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTimer()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
invalidateTimer()
}
private func invalidateTimer() {
countdownTimer()?.invalidate()
countdownTimer = nil
}
}
অনেক অ্যাপে, AVPlayer একটি অন্তর্নির্মিত প্লেয়ারে ভিডিও চালায়। যদি ব্যবহারকারী অন্য স্ক্রিনে নেভিগেট করে, ভিডিওটি স্বয়ংক্রিয়ভাবে বিরাম দেওয়া উচিত। viewDidDisappear-এ এটি বাস্তবায়ন নিশ্চিত করে যে স্ক্রিন সম্পূর্ণরূপে লুকানোর পরে বিরাম ঘটে — এটি ট্রানজিশনের সময় কালো ফ্রেমের ঝলকানি প্রতিরোধ করে।
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if player().timeControlStatus == .playing {
player().pause()
playerLayer().removeFromSuperlayer()
}
player = nil
}
বিরাম দেওয়ার পরে player ভেরিয়েবল শূন্য করা ভিডিও বাফার দ্বারা দখলকৃত মেমরি অতিরিক্তভাবে মুক্ত করে। এই পদ্ধতি দীর্ঘ ভিডিও সহ অ্যাপগুলির জন্য বিশেষভাবে গুরুত্বপূর্ণ, যেখানে বাফার দশ মেগাবাইট নিতে পারে। বিরামকে রেফারেন্স শূন্য করার সাথে যুক্ত করা ব্যাকগ্রাউন্ডে অ্যাপের পদচিহ্ন কমিয়ে দেয়।
viewDidDisappear প্রায়ই viewWillDisappear এবং deinit-এর সাথে বিভ্রান্ত হয়, কিন্তু এই পদ্ধতিগুলির প্রতিটির নিজস্ব দায়িত্বের ক্ষেত্র রয়েছে। তাদের মধ্যে সীমানা বোঝা স্থিতিশীল iOS অ্যাপ আর্কিটেকচারের চাবিকাঠি। ভুল ব্যবহার রিসোর্সের দ্বৈত মুক্তি বা, বিপরীতভাবে, রিসোর্স লিক হতে পারে।
viewDidDisappear এবং viewWillDisappear-এর মধ্যে প্রধান পার্থক্য হল কলের মুহূর্ত। viewWillDisappear কল করা হয় যখন ভিউ এখনও দৃশ্যমান কিন্তু অদৃশ্য হওয়ার প্রস্তুতি নিচ্ছে। এটি দৃশ্যমান ডেটা (ইনপুট ফিল্ডে টেক্সট) সংরক্ষণের জন্য উপযুক্ত। viewDidDisappear অ্যানিমেশন সম্পূর্ণ হওয়ার পরে কল করা হয়, যখন ভিউ নিশ্চিতভাবে দৃশ্যমান নয় — দৃশ্যমান অবস্থার সাথে সম্পর্কিত নয় এমন রিসোর্স মুক্ত করার জন্য আদর্শ।
deinit, viewDidDisappear-এর বিপরীতে, শুধুমাত্র তখন কল করা হয় যখন UIViewController অবজেক্ট মেমরিতে ধ্বংস হয়। যদি নিয়ন্ত্রকটি কেবল লুকানো থাকে (উদাহরণস্বরূপ, একটি মোডাল উইন্ডো দ্বারা আচ্ছাদিত), deinit কল করা হয় না। এই পরিস্থিতিতে, viewDidDisappear সমাপ্তি কার্যক্রম সম্পাদনের একমাত্র বিন্দু। সম্পূর্ণ রিসোর্স পরিষ্কার deinit-এ হওয়া উচিত, কিন্তু viewDidDisappear পরবর্তী উপস্থিতি পর্যন্ত অস্থায়ী মুক্তি পরিচালনা করে।
SwiftUI দিয়ে ডেভেলপ করার সময়, viewDidDisappear পদ্ধতি ব্যবহার করা হয় না — এটি .onDisappear মডিফায়ার দ্বারা প্রতিস্থাপিত হয় যা একইভাবে কাজ করে। তবে, SwiftUI-তে সরাসরি জীবনচক্র নিয়ন্ত্রণের অভাব রয়েছে এবং ডেভেলপাররা রিসোর্স ব্যবস্থাপনার জন্য Combine এবং State অবজেক্টের উপর নির্ভর করে। UIKit অ্যাপগুলির জন্য, viewDidDisappear স্ক্রিন অদৃশ্য হওয়ার ব্যবস্থাপনার জন্য প্রাথমিক টুল হিসাবে রয়ে গেছে।
অভিজ্ঞ iOS ডেভেলপাররাও viewDidDisappear নিয়ে কাজ করার সময় ভুল করেন। আসুন পাঁচটি সবচেয়ে সাধারণ সমস্যা এবং সেগুলি প্রতিরোধের উপায়গুলি পরীক্ষা করি। এই অ্যান্টি-প্যাটার্নগুলি জানা নিয়ন্ত্রক জীবনচক্র সম্পর্কিত কঠিন-থেকে-ধরা বাগগুলি এড়াতে সহায়তা করবে।
থ্রেড নিরাপত্তা-তে বিশেষ মনোযোগ দেওয়া উচিত। যদি viewDidDisappear প্রধান থ্রেডে কল করা হয় (যা UIKit দ্বারা নিশ্চিত), কিন্তু রিসোর্স পরিষ্কারে অ্যাসিঙ্ক্রোনাস অপারেশন জড়িত থাকে, তাহলে ভাগ করা ডেটাতে অ্যাক্সেস সিঙ্ক্রোনাইজ করা আবশ্যক। একটি অ্যাসিঙ্ক্রোনাস কাজ শেষ করার পরে UI আপডেট করতে viewDidDisappear-এর ভিতরে DispatchQueue.main.async ব্যবহার করা একটি সাধারণ কিন্তু সঠিক পদ্ধতি।
আরেকটি গুরুত্বপূর্ণ অ্যান্টি-প্যাটার্ন — viewDidDisappear-এর ভিতরে ডেলিগেট পদ্ধতি কল করা যা একটি নতুন ট্রানজিশন বা মোডাল উপস্থাপনা শুরু করতে পারে। এটি একটি চক্র তৈরি করে যেখানে প্রথম কল সম্পূর্ণ হওয়ার আগে viewDidDisappear আবার কল হতে পারে। Apple জীবনচক্র পদ্ধতির ভিতরে মোডাল উপস্থাপনা এড়ানোর পরামর্শ দেয়, সেগুলিকে পৃথক ইভেন্ট হ্যান্ডলারে স্থানান্তর করে।
সচরাচর জিজ্ঞাসা
viewWillDisappear লুকানোর অ্যানিমেশন শুরুর আগে কল করা হয়, যখন ভিউ এখনও দৃশ্যমান। viewDidDisappear ভিউ সম্পূর্ণরূপে অদৃশ্য হওয়ার পরে কল করা হয়। ডেটা সংরক্ষণের জন্য viewWillDisappear এবং রিসোর্স মুক্ত করার জন্য viewDidDisappear ব্যবহার করুন।
হ্যাঁ, super.viewDidDisappear(animated) কল করা বাধ্যতামূলক। UIKit এই পদ্ধতিটি অভ্যন্তরীণ বিজ্ঞপ্তি এবং ট্রানজিশন অবস্থা সম্পূর্ণ করতে ব্যবহার করে। super কল ছাড়া, UINavigationController এবং UITabBarController-এ ত্রুটি হতে পারে।
হ্যাঁ, ইন্টারঅ্যাকটিভ ডিসমিস iOS 13+ (নিচে সুইপ) এর সাথে, যদি অঙ্গভঙ্গি সম্পূর্ণ না হয় তবে পদ্ধতিটি কল নাও হতে পারে। ইভেন্ট প্রাপ্তির গ্যারান্টি দিতে, UIAdaptivePresentationControllerDelegate এবং presentationControllerDidDismiss পদ্ধতি ব্যবহার করুন।
deinit শুধুমাত্র অবজেক্ট ধ্বংস হলে কল করা হয়, যেখানে viewDidDisappear প্রতিটি লুকানোর সময় কল করা হয়। প্রতিটি ট্রানজিশনে রিসোর্স মুক্ত করার জন্য (উদাহরণস্বরূপ, বিজ্ঞপ্তি থেকে আনসাবস্ক্রাইব), viewDidDisappear ব্যবহার করুন। নিয়ন্ত্রক সরানোর সময় চূড়ান্ত পরিষ্কারের জন্য, deinit ব্যবহার করুন।
SwiftUI-তে, viewDidDisappear-এর পরিবর্তে .onDisappear { } মডিফায়ার ব্যবহার করা হয়। এটি ভিউ হায়ারার্কি থেকে অদৃশ্য হলে কল করা হয়। UIKit-এর বিপরীতে, SwiftUI গ্যারান্টি দেয় না যে onDisappear সমস্ত অ্যানিমেশন পরিস্থিতিতে কল হবে।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন