Grand Central Dispatch in Swift 3: A quick look


Multi-threading และการทำงานแบบ Concurrency เป็นอีกเรื่องสำคัญในการเขียนโปรแกรมสมัยใหม่ และแน่นอนถ้าพูดถึงเรื่องนี้บน Apple Platform สิ่งแรกที่เรานึกถึงกันคงจะเป็น Grand Central Dispatch ซึ่งเป็น C-style API ที่อยู่กับเรามาช้านาน แค่อยู่บน Objective-C ก็ไม่สวยแล้ว พอยิ่งมาอยู่ภาษาสมัยใหม่อย่าง Swift ยิ่งรู้สึกไม่เป็นมิตรใหญ่ที่ต้องมาเขียน C-style แบบนี้ (จริงๆ ก็มี NSOperationQueue มาให้ตั้งนานแล้วนะ แต่ส่วนตัวก็ยังไม่ชินกับมันอยู่ดี)

พอมาใน Swift 3 นั้น Apple ได้ยกเครื่อง libdispatch (อีกชื่อเรียกผ่าน Clang Foundation) หรือ Grand Central Dispatch ที่เราเคยรู้จักใหม่ทั้งหมด ซึ่งวันนี้จะมา Overview ให้ดูคร่าวๆ ว่าหน้าตาเปลี่ยนไปแค่ไหนบ้าง

(ผมเคยกล่าวคร่าวๆ ไว้แล้วที่ภาพรวมความเปลี่ยนแปลงของ Swift 3)

dispatch_async

สำหรับ API ตัวนี้ เมื่อก่อนเราต้องกำหนดวิธีการก่อนว่า เราจะสั่งให้งานที่เรากำลังจะทำเป็นแบบ synchronus หรือ asynchronus จากนั้นค่อยเลือกว่าจะให้ queue ตัวไหนเป็นคนจัดการ แต่ของใหม่จะกลับกระบวนการกัน โดยที่เราสร้าง queue ขึ้นมาก่อนแล้วค่อยจัดการเรื่องวิธีการ

หนึ่งในงานสำคัญที่สุด ที่เราได้ใช้ GCD มากที่สุดหนีไม่พ้นงานที่เราทำอะไรสักอย่างอยู่ที่ background queue และเมื่องานชิ้นนั้นเสร็จก็กลับมาที่ main queue เพื่ออัพเดท View (เช่นการดาวน์โหลดรูปภาพจากอินเตอร์เน็ต) โดยถ้าเราใช้ API ใหม่บน Swift 3 หน้าตาจะออกมาแบบนี้


Wait for the Code ....

Queue Attributes

ค่า Settings ต่างๆ ของ queue มาในรูปแบบของ OptionSet ใน Swift หมดเลย เช่น serial หรือ concurrent, memory และ activity managment หรือ quality of service ซึ่งจะต้องถูกใส่ขณะที่เรากำลังสร้าง queue ขึ้นมาทำงาน

โดยรูปแบบที่ถูกเปลี่ยนไปคือ quality of service โดยจะประกอบไปด้วย .default, .userInteractive, .userInitiated, .utility และ .background ซึ่งมาแทนที่ของเก่าที่ถูกยกเลิกไปตั้งแต่ iOS8 โดยเมื่อเราเทียบกับของเก่าจะได้ดังภาพนี้

  • DISPATCH_QUEUE_PRIORITY_HIGH  =>  .userInitiated
  • DISPATCH_QUEUE_PRIORITY_DEFAULT  =>  .default
  • DISPATCH_QUEUE_PRIORITY_LOW  =>  .utility
  • DISPATCH_QUEUE_PRIORITY_BACKGROUND  =>  .background

ในส่วนของ activity และ memory management เป็นของใหม่ของปีนี้ที่ Apple ใส่เข้ามา ยกตัวอย่างเช่นการสั่งให้ queue เริ่มทำงานในขณะที่แอปของเราอยู่ในสถานะ inactive ด้วย .initiallyInactive หรือการตั้งค่า autorelease ได้เอง ด้วย .autoreleaseInherit, autoreleaseNever และ .autoreleaseWorkItem

Work Items

Apple ไม่ได้อัพเดทเฉพาะส่วนของ Queues เพียงอย่างเดียว แต่ยังอัพเดทในส่วนของ Work Items ด้วยดังนี้


Wait for the Code ....

โดย work item สามารถที่จะสร้างโดยส่ง quality of service และ/หรือ flags ได้ด้วย ซึ่งจะมีผลต่อการถูกส่งไปทำงานของ work item นั้นๆ ซึ่ง flags ที่สามารถใส่เข้าไปได้จะอยู่ในรูปแบบของ OptionSet ประกอบไปด้วย .barrier, .detached, .assignCurrentContext, .noQoS, .inheritQoS และ .enforceQoS

dispatch_once

dispatch_once เป็นอีกหนึ่ง API ที่เป็นประโยชน์มากโดยเฉพาะการใช้ในส่วนของการ initialization และฟังก์ชั่นที่เราต้องการให้ทำงานครั้งเดียวเท่านั้น ซึ่งใน Swift 3 นั้น dispatch_once ได้ถูกยกเลิกไปเลย และ Apple ให้เราใช้ตัวแปรหรือค่าคงที่แบบ global หรือ static แทน


Wait for the Code ....

dispatch_time_t

dispatch_time_t เคยเป็นฟังก์ชั่นที่เอาไว้แปลงจุดของเวลาเป็น UInt64 ซึ่งสามารถที่จะทำงานได้กับ queue ที่เราสร้างขึ้นมา โดยการอัพเดท GCD ได้เปลี่ยนแปลงไปในทางที่ดีขึ้น (ลาก่อย NSEC_PER_SEC) โดยการใช้ dispatch_time_t บ่อยๆ ของผมก็จะเป็นการเขียนฟังก์ชั่น delay ขึ้นมานี่แหละ ส่วนตัวผมชอบใช้มันมากกว่าการใช้ NSTimer นะ โดยเราจะได้รูปแบบนี้เมื่อเขียนใน Swift 3


Wait for the Code ....

ที่เราเห็น .seconds จะเป็นส่วนหนึ่งของ enum type ใหม่ที่ชื่อว่า DispatchTimeInterval ซึ่งในแต่ละกรณีนั้นจะเป็น associated enum ที่รองรับตั้งแต่ .seconds ไปจนถึง .nanoseconds เลยทีเดียว

  • .seconds(Int)
  • .milliseconds(Int)
  • .microseconds(Int)
  • .nanoseconds(Int)
dispatch_assert

ของใหม่ของปีนี้อีกเช่นกัน Apple ได้เพิ่มเติมการตรวจสอบ queue เข้าไปใน libdispatch ด้วย โดยจะมาแทนที่ dispatch_assert ในอดีต ซึ่งการทำงานของมันคือตรวจสอบว่าเราอยู่ใน queue ที่ถูกต้องหรือไม่ ก่อนที่จะเริ่มทำงานใดๆ นี่จะเป็นประโยชน์มากโดยเฉพาะการตรวจสอบก่อนการอัพเดท View ต่างๆ ที่จะต้องทำบน main thread เท่านั้น ลองดูตัวอย่างกันครับ


Wait for the Code ....

Additional Resources 

ยังมีอีกหลายส่วนที่ไม่ได้กล่าวถึงใน Blog นี้เกี่ยวกับการเปลี่ยนแปลงของ GCD บน Swift 3 เนื่องจากในขณะที่เขียนนั้นเอกสารอย่างเป็นการทางจาก Apple ยังไม่เสร็จสมบูรณ์ ส่วนถ้าใครจะติดตามต่อก็ไปได้ที่

Popular posts from this blog

12 วิธี การบริการและดูแลลูกค้าในร้าน Starbucks

[Android Dev] การติดตั้ง Eclipse+AndroidSDK เพื่อพัฒนาโปรแกรมบน Android

"อีสุกอีใส" ประสบการณ์เมื่อต้องมาเป็นตอนอายุ 22