ตอนที่ 9 iOS Swift การจัดการหน่วยความจำ (Memory Management)

  1. ทำความเข้าใจเกี่ยวกับการจัดการหน่วยความจำใน Swift
  2. การนับอ้างอิงอัตโนมัติ (Automatic Reference Counting) (ARC)
  3. การอ้างอิง (references) ที่อ่อนแอ (Weak) และไม่มีเจ้าของ (unowned)
  4. การรั่วไหล (leaks) และการดีบัก (debugging) ของหน่วยความจำ
  5. กลยุทธ์ในการป้องกันการรั่วไหลของหน่วยความจำ

การจัดการหน่วยความจำเป็นส่วนสำคัญของการทำแอพ เนื่องจากการใช้ทรัพยากรหน่วยความจำอย่างมีประสิทธิภาพช่วยให้มั่นใจถึงประสิทธิภาพสูงสุดและลดความเสี่ยงของการหยุดทำงานหรือพฤติกรรมที่ไม่ได้ตั้งใจอื่นๆ ในการทำแอพ iOS นั้น iOS Swift เป็นภาษาโปรแกรมหลักที่ใช้รับทำแอพ และมีระบบการจัดการหน่วยความจำที่แข็งแกร่งที่เรียกว่า Automatic Reference Counting (ARC) ในบทความนี้ เราจะสำรวจพื้นฐานของการจัดการหน่วยความจำใน iOS Swift รวมถึง ARC การอ้างอิงที่อ่อนแอและไม่มีเจ้าของ และเทคนิคสำหรับการดีบักและแก้ไขการรั่วไหลของหน่วยความจำ

1. ทำความเข้าใจเกี่ยวกับการจัดการหน่วยความจำใน Swift

ก่อนดำดิ่งสู่ข้อมูลเฉพาะของการจัดการหน่วยความจำ สิ่งสำคัญคือต้องเข้าใจแนวคิดพื้นฐานที่สนับสนุนวิธีการจัดสรรและยกเลิกการจัดสรรหน่วยความจำในการทำแอพ iOS Swift การจัดการหน่วยความจำเป็นกระบวนการในการติดตามหน่วยความจำที่การทำแอพของคุณใช้ และตรวจสอบให้แน่ใจว่าหน่วยความจำนั้นได้รับการเรียกคืนอย่างถูกต้องเมื่อไม่ต้องการใช้อีกต่อไป ใน iOS Swift การจัดการหน่วยความจำจะถูกจัดการโดยอัตโนมัติโดยกลไก ARC

2. การนับอ้างอิงอัตโนมัติ (Automatic Reference Counting) (ARC)

ARC เป็นระบบการจัดการหน่วยความจำที่ทรงพลังที่จัดการการจัดสรรหน่วยความจำและการจัดสรรคืนให้กับคุณ โดยจะติดตามการอ้างอิงไปยังออบเจกต์ในแอปพลิเคชันของคุณโดยอัตโนมัติ และจัดสรรหน่วยความจำเมื่อไม่ต้องการออบเจ็กต์อีกต่อไป นี่คือภาพรวมระดับสูงของวิธีการทำงานของ ARC:

  • เมื่อคุณสร้างอินสแตนซ์ใหม่ของคลาส ARC จะจัดสรรหน่วยความจำเพื่อเก็บข้อมูลเกี่ยวกับอินสแตนซ์
  • เมื่อใดก็ตามที่คุณกำหนดอินสแตนซ์ให้กับคุณสมบัติ ค่าคงที่ หรือตัวแปร ARC จะเพิ่มจำนวนการอ้างอิงของอินสแตนซ์
  • เมื่อจำนวนการอ้างอิงของออบเจ็กต์ลดลงเหลือศูนย์ หมายความว่าไม่มีการอ้างอิงที่ชัดเจน ARC จะจัดสรรหน่วยความจำที่ออบเจ็กต์ครอบครอง ทำให้ทรัพยากรว่าง

3. การอ้างอิง (references) ที่อ่อนแอ (Weak) และไม่มีเจ้าของ (unowned)

แม้จะมีประโยชน์ของ ARC แต่ก็เป็นไปได้ที่จะสร้างวงรอบการอ้างอิงที่รัดกุม โดยที่วัตถุสองชิ้นหรือมากกว่านั้นอ้างอิงถึงกันและป้องกันไม่ให้มีการจัดสรรซึ่งกันและกัน ซึ่งอาจนำไปสู่การรั่วไหลของหน่วยความจำและเพิ่มการใช้หน่วยความจำ เพื่อหลีกเลี่ยงปัญหานี้ iOS Swift จะให้ข้อมูลอ้างอิงที่อ่อนแอและไม่มีเจ้าของ

  • การอ้างอิงที่อ่อนแอ (Weak References): การอ้างอิงที่อ่อนแอคือการอ้างอิงถึงวัตถุที่ไม่เพิ่มจำนวนการอ้างอิง ช่วยให้คุณสามารถอ้างอิงวัตถุโดยไม่ต้องสร้างรอบการอ้างอิงที่รัดกุม เมื่อออบเจ็กต์ที่อ้างถึงถูกยกเลิกการจัดสรร การอ้างอิงที่อ่อนแอจะถูกตั้งค่าเป็นศูนย์โดยอัตโนมัติ
class MyClass {
    weak var weakReference: OtherClass?
}
  • การอ้างอิงที่ไม่มีเจ้าของ (Unowned References): การอ้างอิงที่ไม่มีเจ้าของนั้นคล้ายกับการอ้างอิงที่อ่อนแอ แต่จะไม่กลายเป็นศูนย์เมื่อวัตถุที่อ้างอิงนั้นถูกยกเลิกการจัดสรร แต่จะสันนิษฐานว่าวัตถุอ้างอิงจะมีอยู่เสมอ การอ้างอิงที่ไม่ได้เป็นเจ้าของมีประโยชน์เมื่อคุณสามารถรับประกันได้ว่าออบเจ็กต์จะไม่ถูกยกเลิกการจัดสรรก่อนออบเจ็กต์ที่อ้างอิง
class MyClass {
    unowned let unownedReference: OtherClass

    init(otherClass: OtherClass) {
        self.unownedReference = otherClass
    }
}

4. การรั่วไหล (leaks) และการดีบัก (debugging) ของหน่วยความจำ

แม้จะมี ARC และการใช้การอ้างอิงที่อ่อนแอและไม่มีเจ้าของในการทำแอพ การรั่วไหลของหน่วยความจำยังคงสามารถเกิดขึ้นได้ในการทำแอพของคุณ การรั่วไหลของหน่วยความจำเกิดขึ้นเมื่อหน่วยความจำถูกจัดสรรแต่ไม่ได้เผยแพร่ ทำให้แอปพลิเคชันของคุณใช้หน่วยความจำมากเกินความจำเป็น หากต้องการตรวจหาและแก้ปัญหาการรั่วไหลของหน่วยความจำ คุณสามารถใช้เทคนิคต่อไปนี้:

  • เครื่องมือ: เครื่องมือเป็นเครื่องมือสร้างโปรไฟล์อันทรงพลังที่จัดทำโดย Xcode ซึ่งช่วยให้คุณวิเคราะห์พฤติกรรมรันไทม์ของแอปพลิเคชันของคุณ เครื่องมือการรั่วไหลและการจัดสรรสามารถช่วยคุณระบุการรั่วไหลของหน่วยความจำและติดตามการจัดสรรหน่วยความจำ
  • Visual Memory Debugger: Visual Memory Debugger ของ Xcode เป็นเครื่องมือโต้ตอบที่แสดงความสัมพันธ์ระหว่างวัตถุในกราฟหน่วยความจำของแอปพลิเคชันของคุณ สามารถช่วยให้คุณมองเห็นรอบการอ้างอิงและปัญหาการจัดการหน่วยความจำอื่นๆ
  • Debug Memory Graph: นอกจาก Visual Memory Debugger แล้ว คุณยังสามารถใช้คุณลักษณะ Debug Memory Graph ใน Xcode เพื่อสำรวจกราฟหน่วยความจำของแอปพลิเคชันของคุณในขณะรันไทม์ คุณสมบัตินี้ช่วยให้คุณตรวจสอบออบเจ็กต์ ความสัมพันธ์ และจำนวนการอ้างอิงในเซสชันการดีบักแบบสด ทำให้ระบุการรั่วไหลของหน่วยความจำและระบุแหล่งที่มาได้ง่ายขึ้น

5. กลยุทธ์ในการป้องกันการรั่วไหลของหน่วยความจำ

เพื่อลดความเสี่ยงของการรั่วไหลของหน่วยความจำในแอปพลิเคชัน Swift ให้พิจารณาแนวทางปฏิบัติที่ดีที่สุดต่อไปนี้:

  • ใช้การอ้างอิงที่อ่อนแอเมื่อเหมาะสม: ใช้การอ้างอิงที่อ่อนแอสำหรับคุณสมบัติที่อาจสร้างวงจรการอ้างอิงที่รัดกุม ซึ่งจะช่วยตัดวงจรและป้องกันการรั่วไหลของหน่วยความจำ
  • คำนึงถึงการปิด (closures): การปิดสามารถบันทึกและจัดเก็บการอ้างอิงถึงตัวแปรและค่าคงที่จากบริบทโดยรอบ ซึ่งอาจนำไปสู่วงจรอ้างอิง ใช้รายการบันทึกเพื่อระบุว่าการปิดควรบันทึกการอ้างอิงอย่างไร ไม่ว่าจะเป็นข้อมูลอ้างอิงที่อ่อนแอหรือไม่มีเจ้าของ เพื่อป้องกันวงจรการอ้างอิง
class MyClass {
    var closure: (() -> Void)?

    init() {
        closure = { [weak self] in
            // Use self? to access properties and methods without creating a strong reference cycle
            self?.doSomething()
        }
    }

    func doSomething() {
        // ...
    }
}
  • ใช้คำสั่งเลื่อน (defer) เพื่อล้างข้อมูล: หากโค้ดของคุณจัดสรรหน่วยความจำด้วยตนเองหรือใช้ทรัพยากรที่ต้องมีการล้างข้อมูลอย่างชัดเจน ให้พิจารณาใช้คำสั่งเลื่อน คำสั่งเลื่อนช่วยให้คุณสามารถระบุโค้ดที่จะถูกดำเนินการเมื่อออกจากขอบเขตปัจจุบัน โดยไม่คำนึงว่าออกเนื่องจากข้อผิดพลาดหรือการดำเนินการตามปกติ
func processFile(filename: String) throws {
    let file = open(filename)
    defer {
        close(file)
    }

    // Process the file...
}
  • ตรวจสอบโค้ดของคุณเป็นประจำ: ตรวจสอบโค้ดของคุณเป็นระยะเพื่อให้แน่ใจว่าคุณปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดสำหรับการจัดการหน่วยความจำ วิธีนี้สามารถช่วยคุณระบุการรั่วไหลของหน่วยความจำที่อาจเกิดขึ้นได้ก่อนที่จะกลายเป็นปัญหา

การจัดการหน่วยความจำเป็นส่วนสำคัญของการทำแอพ iOS และการทำความเข้าใจวิธีการทำงานกับ Automatic Reference Counting (ARC) ของ iOS Swift การอ้างอิงที่อ่อนแอและไม่มีเจ้าของ และเทคนิคการดีบั๊กจะช่วยให้คุณสร้างแอปพลิเคชันที่มีประสิทธิภาพและเชื่อถือได้มากขึ้น การคำนึงถึงแนวทางปฏิบัติที่ดีที่สุดในการจัดการหน่วยความจำและการใช้เครื่องมือที่ Xcode จัดหาให้จะช่วยให้คุณลดการรั่วไหลของหน่วยความจำและมั่นใจได้ว่าการทำแอพของคุณจะยังคงมีประสิทธิภาพสูงสุด

เขียน App iOS Swift

ตอนที่ 8 iOS Swift การทำงานพร้อมกัน (Concurrency)
ตอนที่ 10 iOS Swift การทำงานร่วมกันกับ Objective-C