0Pricing
Objective-C iOS Development for Legacy & Enterprise Apps · บทเรียน

การตรวจหาหน่วยความจำรั่วด้วย Instruments

ใช้ Xcode Instruments เพื่อค้นหาและแก้ไขหน่วยความจำรั่ว วงจรการอ้างอิงค้าง และคอขวดด้านประสิทธิภาพอื่น ๆ ที่เกี่ยวข้องกับหน่วยความจำ

การตรวจหาหน่วยความจำรั่วด้วย Instruments เป็นบทเรียน Objective-C iOS Development for Legacy & Enterprise Apps ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Objective-C iOS Development for Legacy & Enterprise Apps และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Objective-C iOS Development for Legacy & Enterprise Apps มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

What are Memory Leaks?

In Objective-C, a memory leak occurs when your app allocates memory for an object, but then loses all references to that object without deallocating it.

This means the memory is still occupied, but your app can no longer access or free it. Over time, leaks can slow down your app and even cause it to crash.

Introducing Xcode Instruments

Xcode Instruments is a powerful profiling and analysis tool provided by Apple. It helps developers understand the performance of their apps in various areas, including CPU usage, energy consumption, and crucially, memory management.

It's like an X-ray vision for your app's internals!

The 'Leaks' Instrument

Among its many templates, Instruments offers a dedicated 'Leaks' instrument. This tool is specifically designed to detect and visualize memory leaks in your Objective-C applications.

It monitors memory allocations and deallocations, highlighting objects that are still in memory but have become unreachable.

Profiling Your App for Leaks

To start detecting leaks, follow these steps:

  • 1. In Xcode, go to Product > Profile.
  • 2. Xcode will launch Instruments. Select the 'Leaks' template.
  • 3. Click the 'Choose' button.
  • 4. In Instruments, click the 'Record' button (red circle) to start running your app.

Now, interact with your app to try and trigger potential leaks.

Interpreting the Leaks Graph

As your app runs, Instruments will display a timeline graph. Look for red bars appearing in the 'Leaks' track – these indicate that a memory leak has been detected at that point in time.

The height of the bar often correlates with the amount of leaked memory or the number of leaked objects.

Pinpointing the Leak Source

To find out where a leak is happening:

  • 1. Select a red bar (leak spike) in the timeline.
  • 2. In the detail pane below, switch to the 'Call Tree' view.
  • 3. Look for method calls highlighted in red or purple. These often point to the code responsible for allocating the leaked object.

The call stack helps you trace back to the exact line of code!

Common Cause: Retain Cycles

A very common cause of memory leaks in Objective-C (especially with ARC) is a retain cycle (also known as a strong reference cycle).

This occurs when two or more objects hold strong references to each other, forming a closed loop. Because each object thinks another object still needs it, none of them can be deallocated, even if they are no longer needed by the rest of the application.

Example: A Retain Cycle

Here's a simplified example of two classes, MyObject and OtherObject, creating a retain cycle. Notice both properties are strong.

Run this code. You'll see 'initialized' messages but no 'deallocated' messages, indicating a leak.

// MyObject.h
#import <Foundation/Foundation.h>
@class OtherObject;

@interface MyObject : NSObject
@property (strong, nonatomic) OtherObject *other; // Strong reference
- (instancetype)initWithName:(NSString *)name;
@end

// OtherObject.h
#import <Foundation/Foundation.h>
@class MyObject;

@interface OtherObject : NSObject
@property (strong, nonatomic) MyObject *my; // Strong reference
- (instancetype)initWithName:(NSString *)name;
@end

// MyObject.m
#import "MyObject.h"
#import "OtherObject.h"

@interface MyObject ()
@property (strong, nonatomic) NSString *name;
@end

@implementation MyObject
- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = name;
        NSLog(@"MyObject %@ initialized", _name);
    }
    return self;
}

- (void)dealloc {
    NSLog(@"MyObject %@ deallocated", self.name);
}
@end

// OtherObject.m
#import "OtherObject.h"
#import "MyObject.h"

@interface OtherObject ()
@property (strong, nonatomic) NSString *name;
@end

@implementation OtherObject
- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = name;
        NSLog(@"OtherObject %@ initialized", _name);
    }
    return self;
}

- (void)dealloc {
    NSLog(@"OtherObject %@ deallocated", self.name);
}
@end

// main.m
#import <Foundation/Foundation.h>
#import "MyObject.h"
#import "OtherObject.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"--- Starting Retain Cycle Demo ---");

        MyObject *obj1 = [[MyObject alloc] initWithName:@"Object 1"];
        OtherObject *obj2 = [[OtherObject alloc] initWithName:@"Object 2"];

        // Create a strong, circular reference
        obj1.other = obj2;
        obj2.my = obj1;

        NSLog(@"Objects created and linked. Notice no dealloc messages will appear.");
    }
    NSLog(@"--- Retain Cycle Demo Ended ---");
    return 0;
}

Breaking Retain Cycles with 'weak'

To break a retain cycle, one of the references in the loop must be 'weak' instead of 'strong'. A weak reference does not increase an object's retain count, allowing it to be deallocated when no strong references remain.

Run this fixed example. You'll now see the 'deallocated' messages, meaning no leak!

// MyObject.h
#import <Foundation/Foundation.h>
@class OtherObject;

@interface MyObject : NSObject
@property (strong, nonatomic) OtherObject *other;
- (instancetype)initWithName:(NSString *)name;
@end

// OtherObject.h (FIXED: Using 'weak')
#import <Foundation/Foundation.h>
@class MyObject;

@interface OtherObject : NSObject
@property (weak, nonatomic) MyObject *my; // Weak reference to break the cycle
- (instancetype)initWithName:(NSString *)name;
@end

// MyObject.m
#import "MyObject.h"
#import "OtherObject.h"

@interface MyObject ()
@property (strong, nonatomic) NSString *name;
@end

@implementation MyObject
- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = name;
        NSLog(@"MyObject %@ initialized", _name);
    }
    return self;
}

- (void)dealloc {
    NSLog(@"MyObject %@ deallocated", self.name);
}
@end

// OtherObject.m
#import "OtherObject.h"
#import "MyObject.h"

@interface OtherObject ()
@property (strong, nonatomic) NSString *name;
@end

@implementation OtherObject
- (instancetype)initWithName:(NSString *)name {
    self = [super init];
    if (self) {
        _name = name;
        NSLog(@"OtherObject %@ initialized", _name);
    }
    return self;
}

- (void)dealloc {
    NSLog(@"OtherObject %@ deallocated", self.name);
}
@end

// main.m
#import <Foundation/Foundation.h>
#import "MyObject.h"
#import "OtherObject.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"--- Starting Fixed Cycle Demo ---");

        MyObject *obj1 = [[MyObject alloc] initWithName:@"Object 1"];
        OtherObject *obj2 = [[OtherObject alloc] initWithName:@"Object 2"];

        // Assign references. obj2 now has a weak ref to obj1.
        obj1.other = obj2;
        obj2.my = obj1;

        NSLog(@"Objects created and linked. Now dealloc messages should appear!");
    }
    NSLog(@"--- Fixed Cycle Demo Ended ---");
    return 0;
}

Quick Check: Leak Detection

You've noticed your Objective-C app is slowing down over time and consuming more memory than expected. You suspect memory leaks.

Recap: Mastering Memory

You've learned that memory leaks prevent objects from being deallocated, leading to performance issues. Xcode Instruments, particularly the 'Leaks' template, is your go-to tool for identifying these problems.

A common culprit is the retain cycle, where objects strongly reference each other. You can break these cycles by using weak references (@property (weak, nonatomic)) to ensure proper memory management.

คำถามที่พบบ่อย

บทเรียน “การตรวจหาหน่วยความจำรั่วด้วย Instruments” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การตรวจหาหน่วยความจำรั่วด้วย Instruments” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Objective-C iOS Development for Legacy & Enterprise Apps ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Objective-C iOS Development for Legacy & Enterprise Apps มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การตรวจหาหน่วยความจำรั่วด้วย Instruments”

ใช้ Xcode Instruments เพื่อค้นหาและแก้ไขหน่วยความจำรั่ว วงจรการอ้างอิงค้าง และคอขวดด้านประสิทธิภาพอื่น ๆ ที่เกี่ยวข้องกับหน่วยความจำ คุณปฏิบัติ Objective-C iOS Development for Legacy & Enterprise Apps ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Objective-C iOS Development for Legacy & Enterprise Apps หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Objective-C iOS Development for Legacy & Enterprise Apps บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “การตรวจหาหน่วยความจำรั่วด้วย Instruments” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Objective-C iOS Development for Legacy & Enterprise Apps นี้ได้ไหม

ได้ บทเรียน Objective-C iOS Development for Legacy & Enterprise Apps ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตรวจหาหน่วยความจำรั่วด้วย Instruments
  2. การเพิ่มประสิทธิภาพการแสดงผลหน้าจอและการตอบสนอง
  3. เทคนิคการแก้ไขข้อบกพร่องขั้นสูง
  4. การทำโปรไฟล์และลดเวลาเปิดแอป
← กลับไปที่ Objective-C iOS Development for Legacy & Enterprise Apps