OperationQueue — คืออะไร Operation และการจัดการงาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-16 เวลาอ่าน: 8 นาที

OperationQueue คือคิวงานระดับสูงใน iOS และ macOS ที่สร้างขึ้นบน Grand Central Dispatch ตามเอกสารของ Apple Developer, 2026 OperationQueue จัดการอินสแตนซ์ของ Operation ซึ่งเป็นออบเจ็กต์ที่ห่อหุ้มหน่วยการทำงาน แตกต่างจาก DispatchQueue ตรงที่ OperationQueue รองรับการพึ่งพาระหว่างการดำเนินการ ลำดับความสำคัญ การสังเกต KVO และการยกเลิกงานที่กำลังทำงาน OperationQueue จัดการพูลเธรดโดยอัตโนมัติ โดยกระจายการดำเนินการไปยังทรัพยากรระบบที่มีอยู่

ประเด็นสำคัญ

  • OperationQueue — คิวระดับสูงที่รองรับการพึ่งพาระหว่างการดำเนินการ
  • Operation — คลาสนามธรรมสำหรับห่อหุ้มหน่วยการทำงานพร้อมสถานะ
  • BlockOperation — การใช้งาน Operation แบบง่ายสำหรับบล็อกโค้ดเดียว
  • การพึ่งพา กำหนดลำดับการทำงาน: การดำเนินการ B ทำงานหลังจาก A
  • การยกเลิก การดำเนินการรองรับผ่านคุณสมบัติ isCancelled ที่เข้ากันได้กับ KVO

OperationQueue และ Operation คืออะไร

OperationQueue เป็นคลาสจากเฟรมเวิร์ก Foundation ที่จัดการการทำงานของออบเจ็กต์ Operation แตกต่างจาก DispatchQueue ตรงที่ OperationQueue ไม่ต้องการระบุโหมดซีเรียลหรือคอนเคอร์เรนต์อย่างชัดเจน — จำนวนการดำเนินการที่ทำงานพร้อมกันถูกควบคุมโดยคุณสมบัติ maxConcurrentOperationCount ค่า 1 ทำให้คิวเป็นแบบเรียงลำดับ ค่าอื่นใดทำให้เป็นแบบคอนเคอร์เรนต์

Operation เป็นคลาสนามธรรมที่แสดงถึงหน่วยการทำงาน แต่ละการดำเนินการมีสถานะ: ready, executing, finished หรือ cancelled สถานะเหล่านี้เข้ากันได้กับ KVO (การสังเกตค่าคีย์) ซึ่งช่วยให้ตอบสนองต่อการเปลี่ยนแปลงได้ — ตัวอย่างเช่น อัปเดตอินเทอร์เฟซเมื่อการดำเนินการเสร็จสิ้น Operation จัดการแฟล็ก isExecuting และ isFinished โดยอัตโนมัติ

ตามข้อมูลของ Apple (2026) OperationQueue ใช้ GCD ภายในแต่เพิ่มฟังก์ชันการทำงานที่ไม่มีใน DispatchQueue: การพึ่งพา ลำดับความสำคัญ และ การยกเลิก การดำเนินการ หากแอปพลิเคชันเข้าสู่พื้นหลัง OperationQueue จะหยุดการทำงานชั่วคราวและเริ่มใหม่เมื่อกลับมา OperationQueue ยังพิจารณาจำนวนคอร์ของ CPU โดยอัตโนมัติและเลือกจำนวนเธรดที่เหมาะสมที่สุด

วงจรชีวิตของ Operation

แต่ละการดำเนินการผ่านสี่สถานะ: pending (รอดำเนินการ), ready (พร้อม), executing (กำลังดำเนินการ) และ finished (เสร็จสิ้น) สถานะ cancelled สามารถเกิดขึ้นได้ในทุกระยะก่อนเสร็จสิ้น การเปลี่ยนสถานะจะถูกติดตามผ่าน KVO — นี่คือพื้นฐานสำหรับการอัปเดตอินเทอร์เฟซแบบรีแอกทีฟ OperationQueue จะลบการดำเนินการที่เสร็จสมบูรณ์ออกจากคิวโดยอัตโนมัติและแจ้งให้การดำเนินการที่พึ่งพาทราบว่าเงื่อนไขเบื้องต้นสำเร็จแล้ว เพื่อเริ่มการทำงาน

Operation และ BlockOperation: การใช้งานงาน

Operation เป็นคลาสนามธรรมที่ต้องการการแทนที่เมธอด main() หรือ start() โค้ดงานถูกวางในเมธอด main() และสถานะ isExecuting และ isFinished จะถูกจัดการโดยอัตโนมัติ สำหรับการดำเนินการแบบอะซิงโครนัส จำเป็นต้องแทนที่ start() และจัดการแฟล็กสถานะด้วยตนเอง

BlockOperation เป็นการใช้งาน Operation แบบรูปธรรมที่ทำงานบล็อกโค้ดหนึ่งบล็อกหรือมากกว่า BlockOperation จะกลายเป็นคอนเคอร์เรนต์หากคุณเพิ่มหลายบล็อกผ่าน addExecutionBlock() การดำเนินการจะเสร็จสมบูรณ์หลังจากบล็อกที่เพิ่มทั้งหมดทำงานเสร็จเท่านั้น BlockOperation เป็นทางเลือกที่สะดวกสำหรับงานง่าย ๆ โดยไม่ต้องสืบทอด

ลักษณะOperationBlockOperation
ประเภทคลาสนามธรรมรูปธรรม
การสืบทอดจำเป็นไม่จำเป็น
อะซิงโครนัสจัดการ KVO ด้วยตนเองอัตโนมัติ
บล็อกโค้ดหนึ่งใน main()หนึ่งหรือมากกว่า
การใช้งานงานซับซ้อนที่มีสถานะงานง่ายครั้งเดียว
เหมาะสำหรับการพึ่งพา การยกเลิก ความคืบหน้าบล็อกด่วน การเสร็จสิ้น
หน่วยความจำสูงกว่าเนื่องจาก KVO และสถานะน้อยที่สุด เบา

การสร้าง Operation แบบกำหนดเอง

เพื่อสร้างการดำเนินการแบบกำหนดเอง ให้สืบทอดจาก Operation และแทนที่ main() ภายใน ให้ตรวจสอบแฟล็ก isCancelled ก่อนการดำเนินการที่มีต้นทุนสูงเพื่อให้แน่ใจว่าสามารถยกเลิกได้อย่างรวดเร็ว ซึ่งสำคัญสำหรับการดาวน์โหลดไฟล์ขนาดใหญ่หรือการประมวลผลข้อมูลเป็นชุด การเลือกระหว่าง Operation และ BlockOperation ขึ้นอยู่กับความซับซ้อนของงาน: สำหรับการกระทำง่ายครั้งเดียว BlockOperation ก็เพียงพอ สำหรับตรรกะที่ใช้ซ้ำได้พร้อมสถานะ ให้สืบทอดจาก Operation

การพึ่งพาและลำดับความสำคัญของการดำเนินการ

การพึ่งพา เป็นข้อได้เปรียบหลักของ OperationQueue เหนือ DispatchQueue เมธอด addDependency(_:) ระบุว่าการดำเนินการ B จะทำงานหลังจากที่การดำเนินการ A เสร็จสมบูรณ์เท่านั้น การพึ่งพาสร้างกราฟแบบมีทิศทางไม่มีวงจร (DAG): หากเพิ่มการพึ่งพาแบบวงจร คิวจะละเว้นและการดำเนินการจะไม่เริ่มทำงาน

ลำดับความสำคัญ ของการดำเนินการถูกกำหนดผ่านคุณสมบัติ queuePriority ด้วยค่า: .veryLow, .low, .normal, .high, .veryHigh ลำดับความสำคัญมีผลต่อลำดับการเริ่มต้นระหว่างการดำเนินการที่พร้อม แต่ไม่แทนที่การพึ่งพา OperationQueue จะแก้ไขการพึ่งพาก่อน จากนั้นจึงใช้ลำดับความสำคัญระหว่างการดำเนินการที่มีอยู่

ตัวอย่างการพึ่งพาในทางปฏิบัติ

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

การจำกัดความขนาน

คุณสมบัติ maxConcurrentOperationCount จำกัดจำนวนการดำเนินการที่ทำงานพร้อมกัน ค่า 1 สร้างคิวแบบเรียงลำดับ ค่าเริ่มต้น (NSOperationQueueDefaultMaxConcurrentOperationCount) เหมาะสมที่สุดสำหรับระบบและขึ้นอยู่กับโหลดปัจจุบันของอุปกรณ์ การกำหนดค่าพารามิเตอร์นี้อย่างเหมาะสม ป้องกันการใช้ทรัพยากรมากเกินไป: สำหรับการโหลดภาพ 4–6 การดำเนินการแบบขนานก็เพียงพอ สำหรับงานที่ใช้ CPU มาก ให้ใช้จำนวนคอร์ของโปรเซสเซอร์

OperationQueue vs DispatchQueue: การเปรียบเทียบ

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

  • DispatchQueue — เบา เร็ว โดยไม่มีโอเวอร์เฮดของออบเจ็กต์ Operation
  • OperationQueue — รองรับการพึ่งพา การยกเลิก KVO และลำดับความสำคัญ
  • DispatchQueue — เหมาะสำหรับงาน async/asyncAfter อย่างง่ายและการซิงโครไนซ์แบบซีเรียล
  • OperationQueue — ขาดไม่ได้สำหรับอัลกอริทึมทีละขั้นตอนที่มีขั้นตอนเรียงลำดับ
  • DispatchQueue — ผสานรวมกับ Swift Concurrency (async/await) ผ่าน Continuation

ตามข้อมูลของ Ray Wenderlich (2025) ในโครงการ iOS ขนาดใหญ่ OperationQueue ใช้สำหรับการโหลดเนื้อหาพร้อมความคืบหน้าและการยกเลิก ในขณะที่ DispatchQueue ใช้สำหรับการดำเนินการอะซิงโครนัสอื่น ๆ ทั้งหมด อัตราส่วนประมาณ 20 ต่อ 80 โดย DispatchQueue มีมากกว่า

ตัวอย่างโค้ดกับ OperationQueue ใน Swift

มาดูสามตัวอย่าง: BlockOperation อย่างง่าย Operation แบบกำหนดเองพร้อม การพึ่งพา และการดำเนินการที่ยกเลิกได้สำหรับการโหลดข้อมูล

BlockOperation พร้อมการเสร็จสิ้น

กรณีที่ง่ายที่สุด — ทำงานบล็อกบน OperationQueue และจัดการผลลัพธ์ผ่าน completionBlock ทุก Operation มีคุณสมบัติ completionBlock ในตัว ซึ่งถูกเรียกหลังจาก main() เสร็จสิ้น

swift
let queue = OperationQueue()
let operation = BlockOperation()
operation.addExecutionBlock {
    let data = NetworkService.fetchData()
    OperationQueue.main.addOperation {
        self.updateUI(data)
    }
}
queue.addOperation(operation)

การพึ่งพาระหว่างการดำเนินการ

การพึ่งพา รับประกันว่า parseOperation จะเริ่มทำงานหลังจาก downloadOperation เสร็จสมบูรณ์เท่านั้น ซึ่งช่วยลดความจำเป็นในการเรียกกลับที่ซ้อนกัน

swift
let download = BlockOperation { self.downloadJSON() }
let parse = BlockOperation { self.parseJSON() }
parse.addDependency(download)

let queue = OperationQueue()
queue.addOperations([download, parse], waitUntilFinished: false)

การดำเนินการแบบกำหนดเองที่ยกเลิกได้

แทนที่ main() ด้วยการตรวจสอบ isCancelled เป็นระยะ ซึ่งช่วยให้การดำเนินการหยุดทันทีเมื่อถูกยกเลิก โดยไม่ต้องรอให้การดำเนินการที่มีต้นทุนสูงเสร็จสิ้น

swift
class ImageLoadOperation: Operation {
    override func main() {
        guard !self.isCancelled else { return }
        let image = self.downloadImage()
        guard !self.isCancelled else { return }
        OperationQueue.main.addOperation { self.display(image) }
    }
}

การยกเลิกการดำเนินการและการสังเกต KVO

การยกเลิก การดำเนินการตั้งค่าแฟล็ก isCancelled เป็น true แต่ไม่ได้หยุดเมธอด main() ที่กำลังทำงาน โค้ดภายใน main() ต้องตรวจสอบ isCancelled ด้วยตัวเองและยุติเมื่อจำเป็น นี่คือการตัดสินใจทางสถาปัตยกรรมของ Apple — ที่ช่วยให้นักพัฒนาปล่อยทรัพยากรอย่างถูกต้องเมื่อยกเลิก

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

การจัดการการยกเลิกผ่าน KVO

การสมัครรับ isCancelled ผ่าน KVO ช่วยให้อัปเดตอินเทอร์เฟซเมื่อยกเลิกการดำเนินการ — ตัวอย่างเช่น แสดงตัวยึดตำแหน่งแทนการดาวน์โหลดที่ถูกยกเลิก คุณสมบัติ isCancelled เข้ากันได้กับ KVO ทำให้สะดวกสำหรับไปป์ไลน์แบบรีแอกทีฟ

แนวทางปฏิบัติที่ดีที่สุดสำหรับการทำงานกับ OperationQueue

อย่าสร้างการดำเนินการจำนวนมาก — แต่ละ Operation เป็นออบเจ็กต์แยกต่างหากในหน่วยความจำ หากงานสั้นและไม่ต้องการการพึ่งพา ให้ใช้ DispatchQueue โดยตรง OperationQueue เหมาะสมสำหรับสถานการณ์ที่ซับซ้อนที่มีการพึ่งพาอย่างชัดเจน การยกเลิก และการติดตามความคืบหน้า

ตรวจสอบ isCancelled ก่อนการดำเนินการที่มีต้นทุนสูง ภายในเมธอด main() ในกรณีของการดาวน์โหลดไฟล์หรือการประมวลผลภาพ การตรวจสอบหลังจากแต่ละขั้นตอนสำคัญช่วยให้ตอบสนองต่อการยกเลิกได้อย่างรวดเร็ว ใช้ if isCancelled { return } ที่จุดเริ่มต้นของ main() และหลังแต่ละการดำเนินการหลัก

จัดการ completionBlock อย่างถูกต้อง คุณสมบัติ completionBlock ของการดำเนินการถูกเรียกหลังจาก main() เสร็จสิ้น แม้ว่าการดำเนินการจะถูกยกเลิก ตรวจสอบ isCancelled ภายใน completionBlock เพื่อหลีกเลี่ยงการอัปเดตอินเทอร์เฟซด้วยข้อมูลที่ผิดพลาด OperationQueue.main เป็นคิวที่ปลอดภัยต่อเธรดสำหรับการดำเนินการอินเทอร์เฟซ คล้ายกับ DispatchQueue.main

หลีกเลี่ยงการพึ่งพาแบบวงจร — ทำให้ไม่มีการดำเนินการใดในวงจรเริ่มทำงาน OperationQueue ไม่ตรวจจับวงจรโดยอัตโนมัติ: ถ้า A พึ่งพา B และ B พึ่งพา A ทั้งคู่จะอยู่ในสถานะ ready ตลอดไป วางแผนกราฟการพึ่งพาล่วงหน้า

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

OperationQueue แตกต่างจาก DispatchQueue อย่างไร?

OperationQueue สร้างขึ้นบน GCD และเพิ่มการพึ่งพา ลำดับความสำคัญ KVO และการยกเลิกการดำเนินการ DispatchQueue เป็นเครื่องมือที่เบากว่าสำหรับงานอะซิงโครนัสอย่างง่ายโดยไม่มีความสามารถเหล่านี้

จะทำให้คิวเป็นแบบเรียงลำดับได้อย่างไร?

ตั้งค่าคุณสมบัติ maxConcurrentOperationCount เป็น 1 ซึ่งจะเปลี่ยน OperationQueue ให้เป็นคิวแบบเรียงลำดับในขณะที่คงข้อดีทั้งหมด — การพึ่งพา ลำดับความสำคัญ และการยกเลิก

สามารถยกเลิกการดำเนินการที่กำลังทำงานได้หรือไม่?

เมธอด cancel() ตั้งค่าแฟล็ก isCancelled แต่ไม่ได้หยุดเมธอด main() ที่กำลังทำงาน โค้ดการดำเนินการต้องตรวจสอบ isCancelled ด้วยตัวเองและยุติ การยกเลิกทำงานเฉพาะกับการดำเนินการที่รอดำเนินการและพร้อมเท่านั้น

เมื่อใดควรใช้ Operation แทน BlockOperation?

คุณควรสืบทอดจาก Operation เมื่อต้องการ การจัดการสถานะ อะซิงโครนัส หรือการนำตรรกะกลับมาใช้ใหม่ BlockOperation เหมาะสำหรับงานง่ายครั้งเดียวโดยไม่ต้องสืบทอด

OperationQueue บล็อกเธรดหลักหรือไม่?

ไม่ เว้นแต่คุณจะเรียก waitUntilFinished ด้วยพารามิเตอร์ true บนเธรดหลัก การดำเนินการทำงานบนเธรดพื้นหลังโดยค่าเริ่มต้น และผลลัพธ์จะถูกส่งกลับผ่าน OperationQueue.main

สรุป

  • OperationQueue — คิวระดับสูงที่มีการพึ่งพา ลำดับความสำคัญ และการยกเลิกการดำเนินการ
  • Operation — คลาสนามธรรมสำหรับห่อหุ้มงานด้วยสถานะที่เข้ากันได้กับ KVO
  • BlockOperation — การใช้งานแบบง่ายสำหรับบล็อกโค้ดหนึ่งหรือมากกว่า
  • การพึ่งพา กำหนดลำดับการทำงานระหว่างการดำเนินการผ่านกราฟที่ไม่มีวงจร
  • การยกเลิก ต้องการการตรวจสอบ isCancelled ด้วยตนเองภายในเมธอด main() ของการดำเนินการ
  • maxConcurrentOperationCount = 1 เปลี่ยนคิวเป็นโหมดเรียงลำดับ
  • OperationQueue vs DispatchQueue — เลือก OperationQueue เฉพาะเมื่อต้องการการพึ่งพาหรือ KVO

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม