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

การแยกส่วนของแอกเตอร์และ nonisolated

ให้เหตุผลเกี่ยวกับขอบเขตการแยกส่วน

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

การแยกการเข้าถึงของแอกเตอร์คืออะไร

การแยกการเข้าถึงของแอกเตอร์ หมายความว่าสถานะที่เปลี่ยนแปลงได้ของแอกเตอร์จะถูกแตะต้องได้เฉพาะโค้ดที่ทำงานอยู่บนแอกเตอร์นั้น

รันไทม์จะจัดลำดับการเข้าถึง ดังนั้นงานสองงานจะไม่แก้ไขสถานะพร้อมกัน ซึ่งช่วยกำจัดสภาวะแข่งขันของข้อมูล

actor Counter {
    private var value = 0
    func increment() { value += 1 }
}

การเรียกใช้แอกเตอร์

จากภายนอกแอกเตอร์ การเข้าถึงสมาชิกที่ถูกแยกการเข้าถึงจะเป็นแบบ อะซิงโครนัส คุณต้องใช้ await เพราะการเรียกอาจหยุดรอจนกว่าแอกเตอร์จะว่าง

let counter = Counter()
func useCounter() async {
    await counter.increment()
}

ภายในแอกเตอร์: แบบซิงโครนัส

ภายในเมธอดของแอกเตอร์เอง คุณอยู่ในขอบเขตที่แยกการเข้าถึงอยู่แล้ว จึงเข้าถึงสถานะแบบซิงโครนัสได้ โดยไม่ต้องใช้ await กับ self

actor Counter {
    private var value = 0
    func incrementTwice() {
        value += 1 // synchronous: already isolated
        value += 1
    }
}

สมาชิกที่ไม่แยกการเข้าถึง

กำกับสมาชิกด้วย nonisolated เมื่อสมาชิกนั้นไม่แตะต้องสถานะที่เปลี่ยนแปลงได้ สมาชิกดังกล่าวทำงานแบบซิงโครนัสจากที่ใดก็ได้ โดยไม่ต้องใช้ await

วิธีนี้เหมาะอย่างยิ่งสำหรับค่าที่คำนวณจากข้อมูลที่ไม่เปลี่ยนแปลงเท่านั้น

actor User {
    let id: Int
    var sessionCount = 0
    init(id: Int) { self.id = id }
    nonisolated var label: String { "User #\(id)" }
}

เหตุใดการไม่แยกการเข้าถึงจึงปลอดภัย

สมาชิก nonisolated สามารถอ่านได้เฉพาะสถานะที่ ไม่เปลี่ยนแปลง (let) หรือสถานะที่ส่งต่อได้ในลักษณะอื่นเท่านั้น

คอมไพเลอร์จะปฏิเสธความพยายามใด ๆ ที่เข้าถึงสถานะซึ่งแยกการเข้าถึงและเปลี่ยนแปลงได้จากบริบทที่ไม่แยกการเข้าถึง

actor User {
    let id: Int
    var sessionCount = 0
    init(id: Int) { self.id = id }
    // Error: cannot read mutable sessionCount here
    // nonisolated var bad: Int { sessionCount }
}

การไม่แยกการเข้าถึงกับโปรโตคอล

nonisolated เป็นสิ่งจำเป็นเมื่อแอกเตอร์สอดคล้องกับโปรโตคอลแบบซิงโครนัส เมธอดของโปรโตคอลไม่สามารถเป็นแบบอะซิงโครนัสได้ ดังนั้นจึงต้องหลีกเลี่ยงสถานะที่ถูกแยกการเข้าถึง

actor Item: CustomStringConvertible {
    let name: String
    init(name: String) { self.name = name }
    nonisolated var description: String { "Item: \(name)" }
}

MainActor

@MainActor คือแอกเตอร์ส่วนกลางที่แยกโค้ดให้ทำงานบนเธรดหลัก การอัปเดตส่วนติดต่อผู้ใช้ควรอยู่ที่นี่

ใส่แอตทริบิวต์กำกับชนิด เมธอด หรือคุณสมบัติ เพื่อผูกสิ่งเหล่านั้นไว้กับแอกเตอร์หลัก

@MainActor
final class ViewModel {
    var title = "Hello"
    func refresh() { title = "Updated" }
}

การย้ายข้ามแอกเตอร์

เมื่อคุณเรียกจากแอกเตอร์หนึ่งไปยังอีกแอกเตอร์หนึ่ง รันไทม์จะ ย้าย ไปยังตัวประมวลผลอื่นและหยุดรอ การหยุดรอนั้นเองคือจุดที่ await ปรากฏขึ้น

actor Database { func load() -> Int { 42 } }
@MainActor
func show(_ db: Database) async {
    let v = await db.load() // hop to db actor
    print(v)               // hop back to main
}

การกลับเข้าใหม่ของแอกเตอร์

แอกเตอร์สามารถ กลับเข้าใหม่ได้ เมื่อเมธอดหยุดรอด้วย await แอกเตอร์อาจทำงานอื่นที่อยู่ในคิวก่อนที่การทำงานหลัง await จะดำเนินต่อ

สถานะที่คุณอ่านก่อน await อาจเปลี่ยนไปแล้วหลังจากนั้น ให้ตรวจสอบสมมติฐานอีกครั้งหลังจุดหยุดรอ

actor Store {
    var ready = false
    func prepare() async {
        ready = false
        await Task.yield() // other calls may run here
        ready = true
    }
}

พารามิเตอร์แบบแยกการเข้าถึง

ฟังก์ชันสามารถรับพารามิเตอร์แอกเตอร์แบบ isolated และให้เนื้อความของฟังก์ชันทำงานบนแอกเตอร์นั้นได้ โดยไม่ต้องเป็นสมาชิกของแอกเตอร์

func bump(on counter: isolated Counter) {
    // runs isolated to counter; synchronous access
}

แอกเตอร์ส่วนกลางสำหรับระบบย่อย

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

@globalActor
actor RenderActor {
    static let shared = RenderActor()
}
@RenderActor func draw() { }

ตรวจสอบความเข้าใจ: การแยกการเข้าถึง

ทดสอบความเข้าใจของคุณเกี่ยวกับการแยกการเข้าถึงของแอกเตอร์

สรุป: การแยกการเข้าถึงของแอกเตอร์และการไม่แยกการเข้าถึง

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

@MainActor ผูกโค้ดไว้กับเธรดหลัก แอกเตอร์สามารถกลับเข้าใหม่ได้ สถานะจึงเปลี่ยนแปลงขณะข้าม await และแอกเตอร์ส่วนกลางสามารถแยกระบบย่อยทั้งหมดได้ การเข้าใจกฎเหล่านี้อย่างถ่องแท้คือหัวใจของการทำงานพร้อมกันอย่างปลอดภัย

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

บทเรียน “การแยกส่วนของแอกเตอร์และ nonisolated” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การแยกส่วนของแอกเตอร์และ nonisolated”

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

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

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

บทเรียน “การแยกส่วนของแอกเตอร์และ nonisolated” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ปัญหาการแย่งข้อมูล
  2. โพรโทคอล Sendable
  3. การแยกส่วนของแอกเตอร์และ nonisolated
  4. การย้ายไปใช้การทำงานพร้อมกันแบบเข้มงวด
← กลับไปที่ Swift Academy