วงจรการอ้างอิงและการแก้ด้วย weak/unowned
ค้นหาวงจรการอ้างอิงระหว่างออบเจ็กต์กับคลอสเชอร์ แล้วแก้ด้วยการอ้างอิงแบบ weak และ unowned อย่างปลอดภัย
วงจรการอ้างอิงและการแก้ด้วย weak/unowned เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน
วงจรการอ้างอิงคืออะไร
วงจรการอ้างอิงเกิดขึ้นเมื่ออ็อบเจกต์หรือคลอเชอร์เก็บการอ้างอิงแบบ เข้มแข็งถึงกันและกัน ทำให้ ARC ไม่สามารถลดจำนวนลงเหลือศูนย์ได้ ตัดวงจรด้วย แบบอ่อน หรือ แบบไม่เป็นเจ้าของ
วงจรอ็อบเจกต์ ↔ อ็อบเจกต์
การอ้างอิงแบบเข้มแข็งสองรายการที่ชี้หากันทั้งสองทิศทางจะทำให้เกิดการรั่วไหลของหน่วยความจำ เพราะไม่มีอ็อบเจกต์ใดลดจำนวนการอ้างอิงลงเหลือศูนย์ได้
final class Owner {
var gadget: Gadget?
deinit { print("Owner deinit") }
}
final class Gadget {
var owner: Owner?
deinit { print("Gadget deinit") }
}
// Strong ⇄ strong (cycle)
var o: Owner? = Owner()
var g: Gadget? = Gadget()
o!.gadget = g
g!.owner = o
o = nil // no deinit
g = nil // still no deinit (leak)ตัดวงจรด้วยแบบอ่อน
กำหนดให้ด้านหนึ่งเป็น แบบอ่อน (มักเป็นการอ้างอิงย้อนกลับ เช่น ตัวแทน/owner) เพื่อให้ ARC ปล่อยอ็อบเจกต์ทั้งสองรายการได้
final class Owner2 {
var gadget: Gadget2?
deinit { print("Owner2 deinit") }
}
final class Gadget2 {
weak var owner: Owner2? // weak breaks cycle; becomes nil automatically
deinit { print("Gadget2 deinit") }
}
var o2: Owner2? = Owner2()
var g2: Gadget2? = Gadget2()
o2!.gadget = g2
g2!.owner = o2
o2 = nil // Owner2 deinit
g2 = nil // Gadget2 deinitวงจรคลอเชอร์ (self แบบเข้มแข็ง)
คลอเชอร์จะ จับค่าตัวแปรแบบเข้มแข็งเป็นค่าเริ่มต้น หากอ็อบเจกต์นั้นเป็นเจ้าของคลอเชอร์ด้วย จะทำให้เกิดวงจร
final class TimerClient {
var tick: (() -> Void)?
deinit { print("TimerClient deinit") }
func start() {
// BAD: closure strongly captures self; self keeps tick strongly
tick = {
print("tick from", self) // strong capture of self
}
}
}
var c: TimerClient? = TimerClient()
c!.start()
c = nil // no deinit — closure holds self stronglyตัดวงจรด้วยรายการจับค่า
ใช้ [weak self] (เป็นค่าทางเลือก) เพื่อให้ล้างข้อมูลได้อย่างปลอดภัย ใช้ [unowned self] เฉพาะเมื่อรับประกันได้ว่า self ยังมีชีวิตอยู่ขณะคลอเชอร์ทำงาน
final class TimerClient2 {
var tick: (() -> Void)?
deinit { print("TimerClient2 deinit") }
func start() {
// Use [weak self] when self can go away before tick runs
tick = { [weak self] in
guard let self = self else { return } // safe unwrap
print("tick from", self)
}
// Alternative when lifetime is guaranteed: [unowned self]
// tick = { [unowned self] in print("tick from", self) }
}
}
var c2: TimerClient2? = TimerClient2()
c2!.start()
c2 = nil // deinit now prints — no cycleรายการตรวจสอบ
รายการตรวจสอบ:
- มีการอ้างอิงสองทางหรือไม่ ให้ด้านหนึ่งเป็น แบบอ่อน (เช่น ตัวแทน)
- มีการเก็บคลอเชอร์ไว้ในชนิดหรือไม่ ให้จับค่า [weak self] และแกะค่าทางเลือกอย่างปลอดภัย
- ใช้ [unowned self] เฉพาะเมื่อรับประกันอายุการใช้งานได้เท่านั้น มิฉะนั้นอาจทำให้โปรแกรมขัดข้อง
แบบอ่อนเทียบกับแบบไม่เป็นเจ้าของในคลอเชอร์
ตรวจสอบสั้น ๆ: รายการจับค่าใดปลอดภัยกว่าเมื่ออ็อบเจกต์อาจถูกปล่อย
สรุป
สรุป: ระบุวงจรใน อ็อบเจกต์และคลอเชอร์ แล้วตัดวงจรด้วย แบบอ่อน หรือ แบบไม่เป็นเจ้าของให้เหมาะสม หากไม่แน่ใจ ให้เลือก แบบอ่อน
คำถามที่พบบ่อย
บทเรียน “วงจรการอ้างอิงและการแก้ด้วย weak/unowned” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “วงจรการอ้างอิงและการแก้ด้วย weak/unowned” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “วงจรการอ้างอิงและการแก้ด้วย weak/unowned”
ค้นหาวงจรการอ้างอิงระหว่างออบเจ็กต์กับคลอสเชอร์ แล้วแก้ด้วยการอ้างอิงแบบ weak และ unowned อย่างปลอดภัย คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน
บทเรียน “วงจรการอ้างอิงและการแก้ด้วย weak/unowned” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐาน ARC: strong / weak / unowned
- วงจรการอ้างอิงและการแก้ด้วย weak/unowned
- ชนิดค่าเพื่อลดการใช้ข้อมูลร่วมกัน