@MainActor in Swift 5.5(in Burmese)
ပထမဆုံးပြောချင်တာကတော့ အခုဒီစာကိုရေးနေတဲ့အချိန်မှာ Swift 5.5 က beta ဖြစ်ပြီး XCode 13 မှာဘဲရပါဉီးမယ်။ နောက်ပိုင်း stable ဖြစ်သွားရင် changes တွေ အနည်းနဲ့အများ ရှိကောင်းရှိနိုင်ပါတယ်။
Actor & Global Actor
Apple က ဒီနှစ်မှာ actor model ဆိုတာကို swift language ထဲကို ထည့်သွင်းလာခဲ့ပါတယ်။ Actor isolation က swift stdlib မှာ implement လုပ်လိုက်ပြီဖြစ်ပါတယ်။ Actor တွေရဲ့ အဓိကရည်ရွယ်ချက်ကတော့ swift မှာ concurrency ကို support ပေးတဲ့အခါမှာ lock-based synchronisation တွေထက် ပိုပြီး clean ဖြစ်တဲ့ပုံစံနဲ့ data races ဖြစ်တာတွေကို ကာကွယ်ပေးဖို့ပါ။ Global actor ဆိုတာကတော့ actor တွေကိုသုံးပြီး global states တွေကို concurrent thread တွေကနေ isolate လုပ်ပေးဖို့ဖြစ်ပါတယ်။ Global actor နဲ့ပတ်သက်ပြီး ပိုသိချင်ရင်တော့ SE-0316 မှာ သွားဖတ်ကြည့်လို့ရပါတယ်။ ဒီနေ့ပြောမယ့် @MainActor ဆိုတာကတော့ MainActor struct ရဲ့ global actor wrapper တစ်ခုဖြစ်ပါတယ်။
Why & How MainActor?
Apple developer doc မှာသွားကြည့်မယ်ဆိုရင် UIViewController, UICollectionViewController, UILable, UIView စတာတွေအားလုံးမှာ @MainActor ဆိုတဲ့ actor wrapper တပ်ထားတာကို တွေ့ရပါမယ်။ ကျွန်တော်တို့ရဲ့ view controller တွေအားလုံးဟာ UIViewController ရဲ့ sub class တွေဖြစ်တဲ့အတွက် အလိုလျှောက် main actor တွေဖြစ်သွားပါတယ်။ @MainActor တပ်ထားတဲ့ class နဲ့ သူ့ sub class တွေရဲ့ property တွေ method တွေအားလုံးဟာ main thread ကနေဘဲ ခေါ်မှာဖြစ်ပါတယ်။ အဓိပ္ပာယ်ကတော့ background thread ကနေ ui thread တွေကို DispatchQueue.main.async နဲ့ main thread ပေါ်ကို explicitly dispatch ပြန်လုပ်စရာမလိုတော့ပါဘူး။ ဒါပေမယ့် ဒီလို behaviour ကိုလိုချင်တယ်ဆိုရင် swift ရဲ့ async/await ကိုသုံးမှရပါမယ်။ ဘာကြောင့်လဲဆိုတော့ actors တွေကိုယ်တိုင်ကိုက property တွေကို asynchronously ဘဲ access လုပ်လို့ရတာမို့ completion handler(background thread ဖြစ်နေရင်တောင်) နဲ့ဆိုရင် synchronous context ဖြစ်နေမှာပါ။ အဲ့လိုဆိုရင် main actor ပေါ်ကို အလိုအလျှောက် dispatch လုပ်ပေးဖို့မဖြစ်နိုင်ပါဘူး။
My Suggestion
တစ်ကယ်လို့ ကိုယ့် class က ui logic တွေအများကြီးရှိမယ် ui ကိုလည် update လုပ်ရမယ်ဆိုရင် class type ကို main actor အနေနဲ့သတ်မှတ်ပေးလိုက်တာ ပိုအလုပ်ရှုပ်သက်သာပါတယ်။ တစ်ကယ်လို့ main actor class ထဲမှာမှ non ui logic/func တွေကို main thread ပေါ်ကနေ ဖယ်ချင်တယ်ဆိုရင်တော့ nonisolated ဆိုတဲ့ keyword နဲ့ opt out လုပ်လို့ရပါတယ်။ ကိုယ့်မှာ UIကို manipulate လုပ်မယ့် func တစ်ခုနှစ်ခုလောက်ဘဲရှိမယ်ဆိုရင် func ကိုဘဲ main actor အနေနဲ့ @MainActor func ဆိုပြီး သတ်မှတ်ပေးလို့လည်း ရပါသေးတယ်။
ကျွန်တော့်ရဲ့ article တွေကို သဘောကျနှစ်သက်တယ်ဆိုရင် ကျွန်တော့်ရဲ့ နောက်ထပ်လာမယ့် content တွေမလွတ်သွားအောင် follow လုပ်ထားပေးကြပါခင်ဗျာ။