การอ้างอิงแบบ Weak เทียบกับ Strong
แยกความแตกต่างระหว่างการอ้างอิงแบบ strong และ weak เพื่อป้องกันวงจร retain และจัดการอายุการใช้งานของอ็อบเจ็กต์อย่างมีประสิทธิภาพ
การอ้างอิงแบบ Weak เทียบกับ Strong เป็นบทเรียน Objective-C iOS Development for Legacy & Enterprise Apps ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Objective-C iOS Development for Legacy & Enterprise Apps และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Objective-C iOS Development for Legacy & Enterprise Apps มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
Understanding Object Lifetimes
In Objective-C, managing an object's lifetime is crucial. This means deciding when an object should exist in memory and when it can be safely removed.
References are how we tell the system that we 'care' about an object and want it to stay alive. There are two main types: strong and weak.
Strong References: The Default
A strong reference is the default type for properties and variables in Objective-C when using ARC (Automatic Reference Counting).
- It signifies 'ownership' of an object.
- When an object has at least one strong reference, it cannot be deallocated.
- It increases the object's retain count, ensuring it stays in memory.
Think of it as holding onto something tightly; as long as you hold it, it won't disappear.
Strong Reference Example
Let's see a strong reference in action. The person1 variable holds a strong reference to our Person object. Notice the dealloc method is called when the object is no longer strongly referenced.
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (strong, nonatomic) NSString *name;
- (void)sayHello;
@end
@implementation Person
- (void)sayHello {
NSLog(@"Hello, my name is %@", self.name);
}
- (void)dealloc {
NSLog(@"Person %@ is being deallocated.", self.name);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person1 = [[Person alloc] init];
person1.name = @"Alice";
NSLog(@"Person '%@' created.", person1.name);
[person1 sayHello];
// person1 goes out of scope at the end of @autoreleasepool
// The Person object will be deallocated.
}
return 0;
}The Problem: Retain Cycles
While strong references are essential, they can lead to a common memory management issue called a retain cycle (or strong reference cycle).
This happens when two or more objects hold strong references to each other, forming a closed loop. Because each object is strongly referenced by another in the cycle, their retain counts never drop to zero, and they are never deallocated.
Illustrating a Retain Cycle
Imagine a Parent object strongly references a Child object, and that Child object also strongly references its Parent.
- Parent says: "I own Child."
- Child says: "I own Parent."
Neither can be released because the other is still holding onto it, even if no other part of your app needs them anymore. This leads to a memory leak.
Introducing Weak References
Weak references (declared with __weak or the weak property attribute) are designed to break retain cycles.
- They do not increase an object's retain count.
- They do not signify ownership.
- Crucially, a weak reference automatically becomes
nilwhen the object it points to is deallocated.
This 'nilling out' behavior is very safe and prevents dangling pointers.
Weak Reference Behavior
Observe how a weak reference behaves. Once the last strong reference to an object is released, the object is deallocated, and any weak references pointing to it automatically become nil.
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property (strong, nonatomic) NSString *name;
- (void)dealloc;
@end
@implementation Person
- (void)dealloc {
NSLog(@"Person %@ is being deallocated.", self.name);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *strongPerson = [[Person alloc] init];
strongPerson.name = @"Bob";
__weak Person *weakPerson = strongPerson;
NSLog(@"Before nil: strongPerson = %@, weakPerson = %@", strongPerson.name, weakPerson.name);
strongPerson = nil; // Release the strong reference
NSLog(@"Strong reference set to nil.");
if (weakPerson) {
NSLog(@"Weak Person still exists: %@", weakPerson.name);
} else {
NSLog(@"Weak Person is now nil.");
}
}
return 0;
}Breaking the Retain Cycle
To break a retain cycle, one of the references in the cycle should be weak. In our Parent-Child example, it's common for the 'child' to have a weak reference to its 'parent'.
This way, the parent owns the child, but the child doesn't own the parent, allowing both to be deallocated properly.
#import <Foundation/Foundation.h>
@interface Parent : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) id child; // Strong ref to child
- (void)dealloc;
@end
@interface Child : NSObject
@property (strong, nonatomic) NSString *name;
@property (weak, nonatomic) Parent *parent; // Weak ref to parent
- (void)dealloc;
@end
@implementation Parent
- (void)dealloc {
NSLog(@"Parent %@ is being deallocated.", self.name);
}
@end
@implementation Child
- (void)dealloc {
NSLog(@"Child %@ is being deallocated.", self.name);
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Parent *myParent = [[Parent alloc] init];
myParent.name = @"Mom";
Child *myChild = [[Child alloc] init];
myChild.name = @"Alice";
myParent.child = myChild; // Parent strongly references Child
myChild.parent = myParent; // Child weakly references Parent
NSLog(@"Parent and Child created. Releasing strong variables...");
// Both objects will be deallocated as strong references from outside
// the objects are released and the weak link doesn't prevent deallocation.
}
return 0;
}`__weak` vs. `__unsafe_unretained`
You might encounter __unsafe_unretained, another non-owning reference type. However, always prefer __weak.
__weak: Automatically becomesnilwhen the object is deallocated, preventing crashes.__unsafe_unretained: Does NOT becomenil. If the object is deallocated, the reference becomes a dangling pointer, leading to crashes if you try to access it.
__weak is the safer and standard choice in modern Objective-C with ARC.
Check Your Knowledge
Which statement best describes the primary purpose of a weak reference in Objective-C with ARC?
Recap: Strong vs. Weak
We've explored the critical difference between strong and weak references:
- Strong references: Default, signify ownership, increase retain count, keep objects alive.
- Weak references: Do not signify ownership, do not increase retain count, automatically become
nil, and are essential for breaking retain cycles.
Understanding when to use each is key to preventing memory leaks and writing robust Objective-C code.
คำถามที่พบบ่อย
บทเรียน “การอ้างอิงแบบ Weak เทียบกับ Strong” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การอ้างอิงแบบ Weak เทียบกับ Strong” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Objective-C iOS Development for Legacy & Enterprise Apps ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Objective-C iOS Development for Legacy & Enterprise Apps มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การอ้างอิงแบบ Weak เทียบกับ Strong”
แยกความแตกต่างระหว่างการอ้างอิงแบบ strong และ weak เพื่อป้องกันวงจร retain และจัดการอายุการใช้งานของอ็อบเจ็กต์อย่างมีประสิทธิภาพ คุณปฏิบัติ 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 ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การอ้างอิงแบบ Weak เทียบกับ Strong” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Objective-C iOS Development for Legacy & Enterprise Apps นี้ได้ไหม
ได้ บทเรียน Objective-C iOS Development for Legacy & Enterprise Apps ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐานการจัดการหน่วยความจำแบบ Retain-Release (MRR)
- การนับการอ้างอิงอัตโนมัติ (ARC)
- การอ้างอิงแบบ Weak เทียบกับ Strong
- การแก้วงจรการยึดครองในบล็อก