.task { } — iOS 15 da taqdim etilgan SwiftUI modifikatori bo'lib, View paydo bo'lganda asinxron operatsiyani ishga tushiradi va yo'qolganda avtomatik bekor qiladi. Bekor qilish imkoniyatisiz sinxron kodni bajaradigan .onAppear-dan farqli o'laroq, .task async/await konteksti bilan ishlaydi va View ning hayot aylanishini hisobga oladi: View yo'qolganda SwiftUI yaratilgan Task da cancel() chaqiradi. Bu xotira oqishining oldini oladi va View endi yangilanishi kerak bo'lmaganda operatsiyalarning bajarilishiga yo'l qo'ymaydi. Apple WWDC Session 10132 — Meet async/await in SwiftUI (2024) ma'lumotiga ko'ra, .task SwiftUI-da ma'lumot yuklashning afzal usuli hisoblanadi, chunki u Structured Concurrency bilan xavfsiz ishlaydi va asinxron operatsiyaning hayot vaqtini avtomatik boshqaradi.
Asosiy nuqtalar
.task { } — View ekranda paydo bo'lganda async kontekstida Task yaratadigan View modifikatoridir. SwiftUI berilgan closure-ni fonda ishga tushiradi, asosiy oqim UI operatsiyalari uchun bo'sh qoladi. View yo'qolganda, SwiftUI Structured Concurrency mexanizmi orqali Task-ni avtomatik bekor qiladi — bu asinxron operatsiya natijasi endi hech kimga kerak bo'lmagandan keyin davom etmasligini kafolatlaydi.
Apple — Swift Programming Language (2025) ma'lumotiga ko'ra, .task Swift 5.5 da kiritilgan Structured Concurrency kontseptsiyasidan foydalanadi. Har bir .task ota-ona View vazifasi doirasida bola vazifasini yaratadi. Agar ota-ona vazifasi bekor qilinsa (View yo'qolsa), barcha bola vazifalari ham avtomatik bekor qilinadi. Bu DispatchWorkItem yoki AnyCancellable ga havolalarni qo'lda saqlash bilan solishtirganda asinxron operatsiyalarning hayot aylanishini boshqarishni tubdan soddalashtiradi.
@State + .onAppear da qo'lda chaqirish an'anaviy yondashuvidan farqli o'laroq, .task keyinchalik bekor qilish uchun Task ga havolani saqlashni talab qilmaydi. SwiftUI buni avtomatik bajaradi, bu boilerplate kod miqdorini kamaytiradi va vazifani bekor qilishni unutish xavfini bartaraf etadi.
struct ArticlesView: View {
@State var articles: [Article] = []
@State var error: Error?
var body: some View {
List(articles) { article in
Text(article.title)
}
.task {
do {
articles = await APIClient().fetchArticles()
} catch {
self.error = error
}
}
}
}
Ko'plab dasturchilar ma'lumotlarni .onAppear da yuklashga o'rganib qolgan, ammo async/await va .task paydo bo'lishi bilan bu yondashuv eskirgan. .onAppear kodni sinxron bajaradi — .onAppear ichidagi asinxron operatsiyalar uchun chaqiruvni Task { } ga o'rab olish va mumkin bo'lgan bekor qilish uchun unga qo'lda havola saqlash kerak. .task buni avtomatik bajaradi.
| Xususiyat | .task { } | .onAppear |
|---|---|---|
| Async konteksti | O'rnatilgan async/await | Task { } o'rash talab qiladi |
| Avtobekor qilish | Ha, View yo'qolganda | Yo'q, qo'lda amalga oshirilishi kerak |
| Structured Concurrency | Qo'llab-quvvatlaydi | Qo'llab-quvvatlamaydi |
| Qayta ishga tushirish | Faqat id o'zgarganda | Har safar paydo bo'lganda |
| Apple tavsiyasi | Afzal usul | Sinxron operatsiyalar uchun |
.onAppear hali ham sinxron operatsiyalar uchun foydali — masalan, log yozish yoki UI ni dastlabki sozlash. Ammo asinxron ma'lumot yuklash, tarmoq so'rovlari, ma'lumotlar bazasi yoki fayl tizimi bilan ishlash uchun .task dan foydalaning. Bu arxitektura nuqtai nazaridan xavfsizroq va tozaroq.
// ❌ Eski yondashuv: .onAppear da bekor qilmasdan Task
var loadTask: Task<Void, Never>?
func body() { var body: some View { Text("") }
.onAppear {
loadTask = Task { await loadData() }
}
.onDisappear { loadTask?.cancel() }
// ✅ Zamonaviy yondashuv: .task bekor qilishni boshqaradi
func body() { var body: some View { Text("") }
.task { await loadData() }
.task(id:) modifikatori qo'shimcha parametr — identifikator qabul qiladi. Identifikator qiymati o'zgarganda, SwiftUI joriy vazifani bekor qiladi va yangi identifikator bilan yangisini ishga tushiradi. Bu ma'lumotlar tanlangan parametrga bog'liq bo'lgan ekranlar uchun ideal — masalan, kategoriya bo'yicha maqolalar ro'yxati yoki ID bo'yicha mahsulot tafsilotlari.
struct CategoryView: View {
let categoryId: Int
@State var items: [Item] = []
var body: some View {
List(items) { item in
Text(item.name)
}
.task(id: categoryId) {
await loadItems(for: categoryId)
}
}
func loadItems(for id: Int) async {
do {
items = await APIClient().fetchItems(categoryId: id)
} catch {
// xatoni boshqar
}
}
}
categoryId o'zgarganda, SwiftUI oldingi so'rovni bekor qiladi va yangisini ishga tushiradi. Bu, ayniqsa, kategoriyalarni tez almashtirishda muhim — eski so'rovlar holatni yangilash uchun yangilari bilan raqobatlashmaydi. .task(id:) bo'lmasa, o'zgarishlarni .onChange orqali qo'lda kuzatish va Task-ni qo'lda boshqarish kerak bo'lardi.
.task View yo'qolganda vazifani avtomatik bekor qilsa-da, asinxron operatsiyaning o'zi kooperativ ravishda bekor qilishni tekshirishi kerak. Swift kooperativ bekor qilish modelidan foydalanadi — Task.cancel() bajarishni majburan to'xtatmaydi, faqat isCancelled bayrog'ini o'rnatadi. Vazifa ichidagi kod vaqti-vaqti bilan ushbu bayroqni tekshirishi kerak.
struct LoadingView: View {
@State var progress: Double = 0
var body: some View {
ProgressView(value: progress)
.task {
for i in 0..<100 {
// Bekor qilishni tekshir
try Task.checkCancellation()
await Task.sleep(nanoseconds: 50_000_000)
progress = Double(i + 1) / 100.0
}
}
}
}
Task.checkCancellation() vazifa bekor qilingan bo'lsa CancellationError chiqaradi. Bu tekshirishning eng oddiy usuli — har qanday async kontekstida ishlaydi. Muqobil — qimmat operatsiyalardan oldin Task.isCancelled ni qo'lda tekshirish. URLSession tarmoq so'rovlari vazifa bekor qilinganda avtomatik bekor qilinadi, chunki URLSession Structured Concurrency-ni boshidanoq qo'llab-quvvatlaydi.
.task oddiy JSON yuklashdan TaskGroup bilan murakkab parallel operatsiyalargacha ko'plab stsenariylar uchun mos keladi. Keling, uchta odatiy foydalanish misolini ko'rib chiqaylik.
struct ProfileView: View {
@State var profile: Profile?
@State var isLoading = true
var body: some View {
Group {
if isLoading {
ProgressView()
} else if let profile {
Text(profile.name)
} else {
Text("Yuklab bo'lmadi")
}
}
.task {
defer { isLoading = false }
do {
profile = await APIClient().fetchProfile()
} catch {
// profil nil qoladi
}
}
}
}
struct DashboardView: View {
@State var stats: DashboardStats?
var body: some View {
Text("Boshqaruv paneli")
.task {
stats = await Task {
await withThrowingTaskGroup { group in
group.addTask { await API().fetchUsers() }
group.addTask { await API().fetchOrders() }
group.addTask { await API().fetchRevenue() }
return DashboardStats(
users: try await group.next(),
orders: try await group.next(),
revenue: try await group.next()
)
}
}.value
}
}
}
Eng keng tarqalgan xato — asosiy oqimga o'tmasdan .task ichida UI xususiyatlarini mutatsiya qilish. SwiftUI async kontekstida @State o'zgarganda yangilanishlarni avtomatik asosiy oqimga qaytarsa-da, .task ichida UIKit elementlari bilan to'g'ridan-to'g'ri manipulyatsiyalar crash-ga olib kelishi mumkin.
// ❌ Xato: xato boshqaruvi yo'q
.task {
let data = await fetchData() // xatoda qulab tushadi!
items = data
}
// ✅ To'g'ri: do/catch
.task {
do {
items = await fetchData()
} catch {
errorMessage = error.localizedDescription
}
}
Tez-tez beriladigan savollar
.task View yo'qolganda vazifani avtomatik bekor qiladi va Structured Concurrency-ni qo'llab-quvvatlaydi. .onAppear da Task { } vazifaga qo'lda havola saqlashni va .onDisappear da cancel() chaqirishni talab qiladi. .task shuningdek o'qish osonroq — ma'lumot yuklash View ning hayot aylanishining bir qismi ekanligini aniq ko'rsatadi.
Ha, AsyncSequence yoki AsyncStream ga obuna bo'lish uchun .task ichida for await value in publisher.values dan foydalaning. Bu async/await bilan ham, Publisher.values kengaytmasi orqali Combine bilan ham ishlaydi. View yo'qolganda iteratsiya avtomatik tugaydi va obuna bekor qilinadi.
Ha, agar TabView ichidagi View har bir almashtirishda qayta yaratilsa. iOS 18 dan boshlab TabView View ni xotirada saqlashi mumkin — bu holda .task qayta ishga tushirilmaydi. Har bir almashtirishda ma'lumotlarni qayta yuklash kerak bo'lsa, varaq identifikatori bilan .task(id:) dan foydalaning.
SwiftUI View yo'qolganda vazifani bekor qiladi. URLSession so'rovi vazifa ichida bo'lsa, u ham bekor qilinadi. Agar vazifa kooperativ bekor qilishni qo'llab-quvvatlamasa (masalan, isCancelled ni tekshirmasa), bajarish davom etadi, lekin natijasi holatga qo'llanilmaydi, chunki View endi mavjud emas.
Ha, bitta View ga bir nechta .task modifikatorini qo'shish mumkin. Har biri mustaqil vazifa yaratadi. Bu turli ma'lumot manbalarini ajratish uchun qulay: biri profil yuklash, ikkinchisi WebSocket ga obuna bo'lish, uchinchisi geolokatsiyani kuzatish uchun.
Xulosa
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.