شناسایی نشت حافظه با ابزارهای Xcode — از صفر تا صد
در این مقاله کوتاه با شیوه تولید و همچنین شناسایی نشت حافظه با استفاده از ابزارهای Xcode به نام گراف حافظه و leaks آشنا میشویم. اپلیکیشن نمونه دو صفحه را نشان میدهد. در صفحه نخست یک دکمه وجود دارد که وقتی روی آن ضربه بزنیم ما را به صفحه دوم میبرد. در این صفحه عامدانه یک نشت حافظه با استفاده از یک چرخه ایجاد کردهایم. گردش کار به صورت زیر است:
- ابتدا ابزار leaks را در Xcode باز میکنیم و دکمه record را فشار میدهیم.
- زمانی که اپلیکیشن به صورت خودکار باز شد، روی دکمه ناوبری میزنیم که کنترلر نمای دارای نشت را ارائه میکند.
- به سادگی با استفاده از دکمه بازگشت ناوبری برمیگردیم.
- در نهایت تأثیر را در ابزار Leadks و گراف حافظه بررسی میکنیم.
سورس کد این راهنما را میتوانید در این ریپوی گیتهاب (+) ملاحظه کنید.
شروع
فرض کنید که زیرکلاس سادهای به نام UIViewController داریم:
1import UIKit
2
3class FirstViewController: UIViewController {
4
5 override func viewDidLoad() {
6 super.viewDidLoad()
7 self.view.backgroundColor = .white
8
9 self.view.addSubview(button)
10 button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
11 button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
12 }
13
14 @objc func buttonTapped() {
15 self.navigationController?
16 .pushViewController(LeakingViewController(), animated: true)
17 }
18
19 lazy var button: UIButton = {
20 let button = UIButton()
21 button.setTitle(" Navigate ", for: .normal)
22 button.setTitleColor(.black, for: .normal)
23 button.layer.cornerRadius = 5
24 button.layer.borderColor = UIColor.darkGray.cgColor
25 button.layer.borderWidth = 0.5
26 button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
27 button.translatesAutoresizingMaskIntoConstraints = false
28 return button
29 }()
30}
تنها کاری که این زیرکلاس انجام میدهد این است که کنترلر نمای دارای نشت هدف ما را ارائه میکند:
1import UIKit
2
3class LeakingViewController: UIViewController {
4
5 override func viewDidLoad() {
6 super.viewDidLoad()
7 self.view.backgroundColor = .white
8 self.view.addSubview(titleLabel)
9
10 titleLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
11 titleLabel.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
12
13 viewComponent = ViewComponent(parent: self)
14 }
15
16 var viewComponent: ViewComponent!
17
18 lazy var titleLabel: UILabel = {
19 let label = UILabel()
20 label.text = "Leaking view controller"
21 label.font = UIFont(name: "HelveticaNeue-Bold", size: 25)
22 label.textColor = .darkGray
23 label.numberOfLines = 0
24 label.translatesAutoresizingMaskIntoConstraints = false
25 return label
26 }()
27}
برای ایجاد یک چرخه برجا، یک کلاس به نام ViewComponent ایجاد میکنیم که یک UIViewController به عنوان پارامتر میگیرد:
1import UIKit
2
3class ViewComponent {
4
5 init(parent: UIViewController) {
6 self.parent = parent
7 }
8
9 var parent: UIViewController
10}
در نتیجه روابط زیر را خواهیم داشت:
LeakingViewController ➼ViewComponent ViewComponent ➼LeakingViewController
برای این یک شیء از حافظه رها شود، هیچ شیء دیگری نباید آن را نگهداری یا رسم کند. اما این حالت در این مثال عامدانه نقض شده است.
شناسایی نشت حافظه
اکنون زمان باز کردن ابزار leaks فرا رسیده است:
- Xcode را در بخش چپ-بالای صفحه انتخاب کنید.
- Open Developer Tool را باز کرده و گزینه Instruments را انتخاب کنید.
- سپس گزینه Leaks را انتخاب کرده و مطمئن شوید که اپلیکیشن و دستگاه هدف خود را به درستی انتخاب کردهاید:
- در نهایت روی دکمه record بزنید.
اکنون اپلیکیشن باز میشود و تنها کاری که باید انجام دهید این است که روی دکمه ناوبری بزنید و سپس دکمه بازگشت LeakingViewController را بفشارید.
نتیجه زیر به دست میآید:
آیکون قرمز به این معنا است که در جایی از اپلیکیشن با نشت حافظه مواجه هستیم. برای مشاهده اشیای تخصیص نیافته واقعی از ابزار گراف حافظه Xcode استفاده میکنیم.
میبینیم که علیرغم ارائه و خروج از LeakingViewController، همچنان همراه با ViewComponent در گراف حافظه حضور دارد:
سخن پایانی
leaks در Xcode ابزار بسیار کارآمدی است. کافی است روی دکمه record کلیک کنیم و در اپلیکیشن حرکت نماییم تا اقداماتی در سراسر یک اپلیکیشن بزرگ انجام یابند و این ابزار محلهای نشست حافظه را نشان دهد. همچنین روشی برای ثبت سوابق و مرور آنها در مراحل بعدی وجود دارد.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش برنامهنویسی Swift (سوئیفت) برای برنامهنویسی iOS
- مجموعه آموزشهای دروس علوم و مهندسی کامپیوتر
- آموزش سوئیفت (Swift) — مجموعه مقالات مجله فرادرس
- عملگرهای سفارشی در سوئیفت — از صفر تا صد
==