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

การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด

ทำความเข้าใจว่าการอ้างอิงร่วมกันทำให้เกิดข้อผิดพลาดได้อย่างไร และชนิดค่าช่วยป้องกันปัญหาเหล่านี้อย่างไร

การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

ยินดีต้อนรับ

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

ชนิดค่าไม่มีการอ้างอิงร่วม

```swift var a = [1,2,3] var b = a // independent copy a.append(4) print(b) // [1,2,3] — unchanged ``` การกำหนดค่าชนิดค่าแต่ละครั้งจะสร้างสำเนาที่เป็นอิสระจากกัน

ชนิดอ้างอิงมีการอ้างอิงร่วม

```swift class Counter { var value = 0 } let a = Counter() let b = a // SAME object a.value += 1 print(b.value) // 1 — b sees the change! ``` ทั้ง `a` และ `b` ชี้ไปยังออบเจ็กต์เดียวกันบนฮีป

การอ้างอิงร่วมในพารามิเตอร์ฟังก์ชัน

```swift func increment(_ c: Counter) { c.value += 1 } let shared = Counter() increment(shared) print(shared.value) // 1 — mutated by the function ``` คลาสถูกส่งผ่านด้วยการอ้างอิง — ฟังก์ชันจึงเปลี่ยนแปลงค่าต้นฉบับ

ปัญหา: สถานะที่เปลี่ยนแปลงร่วมกัน

```swift class Cache { var items: [String] = [] } var cache = Cache() var cache2 = cache // aliased! cache.items.append("data") print(cache2.items) // ["data"] — unexpected! ``` นี่คือสาเหตุที่ส่วนต่าง ๆ ของโค้ดซึ่งดูเหมือนไม่เกี่ยวข้องกันส่งผลกระทบต่อกัน

แก้ปัญหาด้วยชนิดค่า

```swift struct Cache { var items: [String] = [] } var cache = Cache() var cache2 = cache // independent copy cache.items.append("data") print(cache2.items) // [] — unaffected ```

แก้ปัญหาด้วยคลาสที่คัดลอกได้

```swift func process(_ c: Counter) { var local = Counter() local.value = c.value // copy values, not reference local.value += 1 } ``` เมื่อคุณต้องการความหมายแบบการอ้างอิงแต่ไม่ต้องการการอ้างอิงร่วม ให้คัดลอกค่าอย่างชัดเจน

ความปลอดภัยของเธรดและการอ้างอิงร่วม

การใช้อ้างอิงร่วมจะอันตรายเป็นพิเศษเมื่อเกิดขึ้นข้ามเธรด: ```swift // Thread 1: cache.items.append("a") // Thread 2 simultaneously: cache.items.append("b") // ❌ data race! ``` ประเภทค่าใน Swift Concurrency ป้องกันปัญหานี้ได้โดยค่าเริ่มต้น — มีเพียงแอ็กเตอร์เท่านั้นที่สามารถใช้สถานะที่เปลี่ยนแปลงได้ร่วมกัน

การตรวจจับการใช้อ้างอิงร่วมโดยไม่ตั้งใจ

Thread Sanitizer ของ Xcode (TSan) ตรวจจับการแข่งกันเข้าถึงข้อมูลขณะทำงานได้ โปรดเปิดใช้งานที่ Scheme > Diagnostics > Thread Sanitizer การบังคับใช้เอกสิทธิ์เฉพาะของ Swift ตรวจจับการละเมิดการใช้อ้างอิงร่วมแบบเธรดเดียวสำหรับพารามิเตอร์ `inout` ขณะทำงานได้

รูปแบบการใช้อ้างอิงร่วมโดยตั้งใจ

บางครั้งการใช้อ้างอิงร่วมก็เป็นสิ่งที่ตั้งใจ เช่น แคชส่วนกลาง: ```swift class AppCache { static let shared = AppCache() // intentional shared reference var data: [String: Any] = [:] } ``` โปรดบันทึกให้ชัดเจนว่าการใช้งานร่วมกันเป็นสิ่งที่ตั้งใจ และตั้งต้นด้วยประเภทค่าเพื่อหลีกเลี่ยงการใช้อ้างอิงร่วมโดยไม่ตั้งใจ

ตรวจสอบอย่างรวดเร็ว

เมื่อกำหนดอินสแตนซ์ของคลาสให้กับตัวแปรใหม่ จะเกิดอะไรขึ้น

สรุปทบทวน

ประเด็นสำคัญ: • ประเภทค่า (สตรักต์) — การกำหนดค่าจะสร้างสำเนา จึงไม่สามารถเกิดการใช้อ้างอิงร่วมได้ • ประเภทอ้างอิง (คลาส) — การกำหนดค่าจะแชร์การอ้างอิง จึงอาจเกิดการใช้อ้างอิงร่วมได้ • การใช้อ้างอิงร่วมข้ามเธรด = การแข่งกันเข้าถึงข้อมูล • ควรใช้สตรักต์เป็นค่าเริ่มต้น และใช้คลาสเฉพาะเมื่อต้องการเอกลักษณ์ร่วมกัน • ใช้ TSan และการบังคับใช้เอกสิทธิ์เฉพาะของ Swift เพื่อตรวจจับปัญหา ถัดไป: กราฟที่ผสมประเภทค่าและประเภทอ้างอิง

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

บทเรียน “การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด”

ทำความเข้าใจว่าการอ้างอิงร่วมกันทำให้เกิดข้อผิดพลาดได้อย่างไร และชนิดค่าช่วยป้องกันปัญหาเหล่านี้อย่างไร คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. สแตกกับฮีป: ค่าต่าง ๆ อยู่ที่ใด
  2. การเปลี่ยนแปลง การใช้ร่วมกัน และการอ้างชื่อที่ไม่คาดคิด
  3. กราฟที่มีทั้งค่าและการอ้างอิง
  4. การออกแบบ API ตามความหมายของค่า
← กลับไปที่ Swift Academy