@MainActor — bu nima, qo'llanilishi va Swift asinxron kodidagi xususiyatlari

Muallif: IT Sectr Nashr etilgan: 2026-03-19 O'qish vaqti: 8 daq

@MainActor Swift tilidagi global aktyor bo'lib, kodning asosiy oqimda bajarilishini kafolatlaydi. Apple Developer, 2024 ma'lumotlariga ko'ra, @MainActor UI bilan ishlashda asosiy oqimga o'tishni avtomatlashtiradi va dasturchini DispatchQueue.main.async qo'lda chaqirishdan ozod qiladi. Annotatsiya Swift 5.5 da async/await tizimi bilan birga paydo bo'ldi.

Asosiy fikrlar

  • @MainActor — Swift-da asosiy oqimda bajarilishni kafolatlaydigan global aktyor.
  • async/await tizimi — @MainActor ishlashining asosi.
  • Sinf annotatsiyasi barcha metodlarini avtomatik ravishda asosiy oqimga joylashtiradi.
  • DispatchQueue.main-dan farqli o'laroq, @MainActor oqimni kompilyator darajasida tekshiradi.
  • UI yangilanishlari — @MainActor-ni iOS-ishlanmasida qo'llashning asosiy sohasi.

@MainActor nima?

@MainActor Swift-da global aktyor (global actor) bo'lib, aktyorlarning xususiyatlarini ilovaning asosiy oqimida bajarilish kafolati bilan birlashtiradi. U Swift 5.5 da async/await va strukturali parallellik bilan birga taqdim etilgan Swift parallellik tizimining bir qismidir. Annotatsiya dasturchiga oqimlarni qo'lda almashtirish haqida o'ylamaslikka imkon beradi va UI xatolar sonini kamaytiradi.

Ta'rif va Swift Concurrency-dagi o'rni

Swift-dagi aktyor — bu o'z holatini izolyatsiya qiladigan va faqat bitta oqim uni o'zgartirishi mumkinligini kafolatlaydigan referens turidir. @MainActor — bu ijrochisi asosiy oqim bo'lgan maxsus global aktyor. @MainActor bilan belgilangan har qanday kod asosiy oqimda bajariladi — hatto fon vazifasidan chaqirilgan bo'lsa ham.

@MainActor paydo bo'lishidan oldin, dasturchilar DispatchQueue.main.async orqali qo'lda asosiy oqimga o'tishardi. Bu tez-tez xatolarga sabab bo'lardi: dasturchilar o'tishni unutib, UI-ni asosiy bo'lmagan oqimda yangilab, ishdan chiqishlarga olib kelishardi. @MainActor bu muammoni tur tizimi darajasida hal qiladi.

Yaratilish sabablari

iOS ilovalaridagi ko'pchilik xatolarning manbai UI-xavfsizlik — interfeysni fon oqimidan yangilashdir. Apple @MainActor-ni Swift Concurrency-ga kiritdi, shunda asosiy oqimga o'tish avtomatik va kompilyator tomonidan tekshiriladigan bo'lsin va butun bir runtime xatolar sinfini yo'q qilsin.

@MainActor qanday ishlaydi?

Ishlash printsipi Swift Concurrency ijro tizimiga asoslangan. Oqim @MainActor bilan belgilangan funksiyani chaqirganda, rejalashtiruvchi uni joriy ijrochida to'xtatadi va asosiy oqimda qayta boshlaydi. Kompilyator chaqiruv chegaralarini kuzatadi va xavfsizlikni kafolatlaydi.

Asosiy oqim ijrochisi

@MainActor bajarilishi uchun MainActor.shared javobgardir — ilovaning asosiy oqimi bilan bog'liq ijrochi. Asinxron funksiya @MainActor bilan belgilanganda, u har doim shu ijrochida qayta boshlanadi, asl vazifa qaysi oqimda boshlanganidan qat'iy nazar.

swift
import SwiftUI

class ViewModel: ObservableObject {
    @Published var items: [String] = []

    @MainActor
    func loadData() async {
        let result = await fetchRemoteData()
        items = result  // xavfsiz, MainActor asosiy oqimni kafolatlaydi
    }
}

Aktor kontekstining merosxo'rligi

Agar funksiya @MainActor bilan belgilangan va boshqa asinxron funksiyani chaqirsa, u sukut bo'yicha aktor kontekstini meros qilib oladi. Bu shuni anglatadiki, barcha ichki chaqiruvlar ham asosiy oqimda bajariladi, agar boshqacha ko'rsatilmagan bo'lsa. Kompilyator buni kuzatadi va mos kelmaydigan closure uzatishga urinishda xato beradi.

@MainActor vs DispatchQueue.main

@MainActor va DispatchQueue.main solishtiruvi yangi mexanizm nima uchun xavfsizroq va qulayroq deb hisoblanishini tushunishga yordam beradi, garchi ikkalasi ham bir vazifani — kodni asosiy oqimda bajarishni — hal qilsa.

Tur darajasida xavfsizlik

@MainActor — bu kompilyator darajasida tekshirish. @MainActor funksiyasini xavfsiz bo'lmagan kontekstdan chaqirishga urinsangiz, kompilyator ogohlantirish yoki xato beradi. DispatchQueue.main.async — bu runtime chaqiruvi: kod kompilyatsiya qilinadi, lekin UI-ni fon oqimidan yangilashga urinishda runtime-da ishdan chiqishi mumkin.

Samaradorlik va ortiqchalik

DispatchQueue.main.async navbatga kechikish bilan bajarilishi mumkin bo'lgan blok qo'shadi. @MainActor async/await bilan ortiqcha closurelar yaratmasdan to'g'ridan-to'g'ri ijrochi almashtirishni amalga oshiradi. Bu yukni kamaytiradi va kodni bajarilish vaqti jihatidan oldindan bashorat qilish mumkin qiladi.

swift
// Eski yondashuv
DispatchQueue.main.async {
    self.updateUI()
}

// @MainActor bilan yangi yondashuv
@MainActor
func updateUI() {
    // asosiy oqimda bajariladi
    self.label.text = "Yangilandi"
}
Mezon@MainActorDispatchQueue.main
Tekshirishkompilyatorruntime
Sintaksisannotatsiya (deklarativ)chaqiruv (imperativ)
Yukpast (ijrochi almashtirish)o'rta (closure + navbat)
Sinovdan o'tkazishyuqori (MainActor.shared almashtirilishi mumkin)past (mock qilish qiyin)

iOS loyihalarida @MainActor dan foydalanish

Haqiqiy iOS loyihalarida @MainActor ViewModel qatlamlarida, SwiftUI ko'rinishlarida va UIKit kontrollerlarida qo'llaniladi. Annotatsiya alohida metodlarga ham, butun turga ham qo'llanilishi mumkin.

Sinf yoki strukturaning annotatsiyasi

Sinfni @MainActor bilan belgilash orqali siz uning barcha metodlari va xususiyatlari faqat asosiy oqimda mavjudligini kafolatlaysiz. Bu ayniqsa SwiftUI ko'rinishlari va ObservableObject sinflari uchun qulay: class dan oldin @MainActor qo'shasiz va barcha @Published xususiyatlari xavfsiz tarzda yangilanadi.

swift
@MainActor
final class UserListViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false

    func fetchUsers() async {
        isLoading = true
        users = await api.getUsers()
        isLoading = false
    }
}

Eski kodni o'rash

Oqim almashtirish qo'lda bo'lgan eski UIKit kodi bilan ishlashda, aniq o'tish uchun MainActor.run dan foydalanish mumkin. Bu butun kod bazasini qayta yozmasdan Swift Concurrency-ga bosqichma-bosqich o'tish uchun qulay.

swift
await MainActor.run {
    self.tableView.reloadData()
}

@MainActor cheklovlari

Barcha afzalliklariga qaramay, @MainActor ilova arxitekturasini loyihalashda hisobga olinishi muhim bo'lgan bir qator cheklovlarga ega. Qo'llash chegaralarini tushunish noto'g'ri foydalanishni oldini olishga yordam beradi.

Intensiv foydalanishda samaradorlik

Agar butun chaqiruv zanjiri @MainActor bilan belgilangan bo'lsa, har qanday og'ir ish asosiy oqimda bajariladi va UI muzlashiga olib keladi. Faqat UI qatlamini @MainActor bilan belgilash, biznes mantiq va tarmoq so'rovlarini fon aktyorlarida yoki global ijrochida qoldirish tavsiya etiladi.

Ba'zi APIlar bilan nomoslik

Eski callback-ga asoslangan APIlar (masalan, async/await siz URLSession) aktyor kontekstini qo'llab-quvvatlamaydi. Integratsiya uchun CheckedContinuation bilan o'rash talab qilinadi. Shuningdek, @MainActor performSelector, target-action va UIKitning boshqa asinxron bo'lmagan naqshlari bilan mos kelmaydi.

Ko'p oqimli tuzatish

@MainActor bilan ilovalarni tuzatishda raqobat holatlarini takrorlash qiyinroq, chunki kompilyator ularning ko'pchiligini runtime-da emas, qurish bosqichida oldini oladi. Biroq, bu soxta xavfsizlik hissi yaratishi mumkin: umumiy mutable ob'ektlar bilan (masalan, NSCache yoki umumiy global o'zgaruvchilar) noto'g'ri ishlash hali ham mumkin, agar ular @MainActor bilan belgilanmagan va aniq sinxronizatsiyasiz ishlatilsa.

@MainActor-ni sinovdan o'tkazish

@MainActor UI mantig'ini sinovdan o'tkazishni sezilarli darajada soddalashtiradi, chunki testlarda oqimlarni qo'lda almashtirish zaruratini yo'q qiladi. Biroq, birlik va UI testlarini yozishda hisobga olinishi kerak bo'lgan xususiyatlar mavjud.

MainActor bilan birlik testlari

XCTest da, ijro muhiti avtomatik ravishda asosiy oqim ijrochisini sozlaydi. Test metodi asosiy oqimda bajarilganda, @MainActor funksiyalarini chaqirish qo'shimcha sozlashlarni talab qilmaydi — ular bir xil kontekstda bajariladi. Fon stsenariylarini test qilish uchun Task ichida MainActor.run dan aniq prioritet va ijrochi ko'rsatilgan holda foydalaning, kod fondan chaqirilganda to'g'ri ishlashini alohida tekshirib ko'ring.

Keng tarqalgan yondashuvlardan biri @MainActor bilan ViewModel ni test qilishdir, bunda @Published xususiyatlari asinxron operatsiyalardan keyin to'g'ri yangilanayotgani tekshiriladi. Aktyor kontekstining merosxo'rligi tufayli, test ichidagi await chaqiruvi qo'shimcha DispatchQueue kafolatlari va qo'lda kontekst almashtirishsiz asosiy oqimda bajarilishni kafolatlaydi, bu test yozishni soddalashtiradi.

Refaktoringda izolyatsiyani tekshirish

Mavjud kodni Swift Concurrency-ga refaktor qilishda @MainActor izolyatsiyasini kompilyator orqali tekshiring: @MainActor kontekstidan @MainActor siz sinxron metodlarning har qanday chaqiruvi xato sifatida belgilanadi. Bu xususiyat loyihani bosqichma-bosqich async/await-ga o'tkazish uchun ishlatiladi: ViewModel qatlamini @MainActor sifatida belgilaysiz va kompilyator fon aktyorlariga ko'chirilishi kerak bo'lgan barcha xavfsiz bo'lmagan chaqiruvlarni ajratib ko'rsatadi.

Mock va aktyor konteksti

@MainActor bog'liqliklari uchun mocklar yaratishda async-metodli protokollardan foydalaning, ular qaytariladigan turlar bilan asinxron funksiyalarni e'lon qiladi. Bu aktyor izolyatsiyasini buzmasdan tarmoq xizmatlari, ma'lumotlar bazalari va boshqa tashqi bog'liqliklarni almashtirishga imkon beradi. Kompilyator mock izolyatsiya talablariga javob berishini tekshiradi, fon test oqimlaridan @MainActor kodiga tasodifiy kirishni oldini oladi.

Asinxron operatsiyalarni kutish

@MainActor kodini sinxron sinovdan o'tkazishda asinxron operatsiyalarning tugashini kutish uchun XCTestExpectation dan foydalaning. Testda kutishni o'rnating va asosiy oqimda bajariladigan closure ichida fulfillment-ni bajaring. Agar test cheksiz osilib qolsa — ehtimol, asosiy oqimda chaqiruv sodir bo'lmayapti va aktyor izolyatsiyasini tekshirish kerak. Ijro kontekstini tuzatish uchun test kodi ichida Thread.isMainThread tekshiruvini qo'shish foydalidir.

Tez-tez beriladigan savollar

Butun sinfni @MainActor bilan belgilash majburiymi?

Yo'q, faqat UI-ni yangilaydigan metodlarni belgilash kifoya. Ammo sinfda bir nechta bunday metodlar bo'lsa, butun sinfga @MainActor qo'shish osonroq. Bu uning barcha a'zolari asosiy oqimda bajarilishini kafolatlaydi va kodni saqlashni soddalashtiradi.

@MainActor @globalActor-dan nimasi bilan farq qiladi?

@MainActor — asosiy oqimga bog'langan global aktyorning aniq namunasi. @globalActor — o'z global aktyorlaringizni yaratish uchun protokol. Masalan, loyiha arxitekturasi talab qilsa, fon oqimida kod bajarish uchun @BackgroundActor yaratishingiz mumkin.

@MainActor async/await siz ishlatilishi mumkinmi?

Ha, @MainActor bilan sinxron funksiyalar ham asosiy oqimda bajariladi. Biroq, @MainActor-ning asosiy qiymati aynan async/await bilan ochiladi, asinxron funksiya avtomatik ravishda DispatchQueue.main orqali qo'lda o'tishsiz asosiy oqimda qayta boshlanganda.

@MainActor vazifasini qanday bekor qilish mumkin?

Task.cancel() @MainActor vazifalari bilan oddiy vazifalar kabi ishlaydi. @MainActor vazifasi Task.isCancelled ni tekshirishi yoki CancellationError ni tashlashi mumkin. Bekor qilishda asosiy oqim bloklanmaydi — vazifa eng yaqin to'xtatish nuqtasida bajarilishini to'xtatadi.

Agar @MainActor fon oqimidan chaqirilsa nima bo'ladi?

Kompilyator xavfsizlikni kafolatlaydi: @MainActor funksiyasini fon kontekstidan chaqirsangiz, kompilyator xatoni ko'rsatadi. Asinxron chaqiruvlar uchun chaqiruvchi kodni await bilan belgilash kifoya va ijrochi o'zi asosiy oqimga o'tadi. Sinxron chaqiruvlar uchun MainActor.run orqali aniq o'tish talab qilinadi.

Xulosa

  • @MainActor — Swift-da asosiy oqimda bajarilishni kafolatlaydigan global aktyor.
  • Kompilyator tekshiruvi butun bir UI xavfsizlik xatolar sinfini yo'q qiladi.
  • Butun sinf annotatsiyasi uning barcha metodlarini avtomatik ravishda asosiy oqimga joylashtiradi.
  • MainActor.run — eski kod va sinxron kontekstlar uchun aniq o'tish.
  • DispatchQueue.main-dan farqli o'laroq, @MainActor closure yaratmaydi va ijrochi almashtirishdan foydalanadi.
  • Og'ir hisoblashlar UI muzlashining oldini olish uchun @MainActor ostida bajarilmasligi kerak.
  • Aktor kontekstining merosxo'rligi asinxron chaqiruv zanjirlarini soddalashtiradi va kodni ketma-ket, oldindan bashorat qilish mumkin va UI uchun xavfsiz qiladi.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing