0Pricing
Swift Academy · บทเรียน

วงจรการอ้างอิงและการแก้ด้วย 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. พื้นฐาน ARC: strong / weak / unowned
  2. วงจรการอ้างอิงและการแก้ด้วย weak/unowned
  3. ชนิดค่าเพื่อลดการใช้ข้อมูลร่วมกัน
← กลับไปที่ Swift Academy