شناسایی نشت حافظه با ابزارهای Xcode — از صفر تا صد

۳۲ بازدید
آخرین به‌روزرسانی: ۰۵ مهر ۱۴۰۲
زمان مطالعه: ۲ دقیقه
شناسایی نشت حافظه با ابزارهای 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 کلیک کنیم و در اپلیکیشن حرکت نماییم تا اقداماتی در سراسر یک اپلیکیشن بزرگ انجام یابند و این ابزار محل‌های نشست حافظه را نشان دهد. همچنین روشی برای ثبت سوابق و مرور آن‌ها در مراحل بعدی وجود دارد.

شناسایی نشت حافظه

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۰ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
better-programming
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *