.task { } — bu nədir, async modifieri və View-də məlumat yükləmə

Müəllif: IT Sectr Dərc olunub: 2026-06-26 Oxuma vaxtı: 9 dəq

.task { } — iOS 15-də təqdim edilmiş SwiftUI modifieridir, View görünəndə asinxron əməliyyat işə salır və yox olduqda avtomatik ləğv edir. Sinxron kodu ləğv etmək imkanı olmadan yerinə yetirən .onAppear-dan fərqli olaraq, .task async/await konteksti ilə işləyir və View-in həyat dövrünü nəzərə alır: View yox olduqda SwiftUI yaradılmış Task-da cancel() çağırır. Bu, yaddaş sızmalarının və View-in artıq yenilənməsinə ehtiyac olmadığı halda əməliyyatların yerinə yetirilməsinin qarşısını alır. Apple WWDC Session 10132 — Meet async/await in SwiftUI (2024) məlumatına görə, .task SwiftUI-də məlumat yükləməyin üstünlük verilən üsuludur, çünki Structured Concurrency ilə təhlükəsiz işləyir və asinxron əməliyyatın həyat müddətini avtomatik idarə edir.

Əsas məqamlar

  • .task { } — View görünəndə asinxron məlumat yükləmə üçün SwiftUI modifieri, iOS 15-dən etibarən mövcuddur.
  • Avtomatik ləğv — View yox olduqda SwiftUI Task-ı ləğv edir, yaddaş sızmalarının qarşısını alır.
  • async/await konteksti — .task daxilində DispatchQueue və ya Combine ehtiyacı olmadan async çağırışları mövcuddur.
  • .task(id:) — identifikatorlu variant göstərilən dəyər dəyişdikdə tapşırığı yenidən işə salır.
  • Structured Concurrency — .task paralel əməliyyatlar üçün Structured Concurrency və TaskGroup dəstəkləyir.

SwiftUI-də .task { } nədir

.task { } — View ekranda görünəndə async kontekstində Task yaradan View modifieridir. SwiftUI ötürülən closure-u fon mövzusunda işə salır, əsas mövzu UI əməliyyatları üçün sərbəst qalır. View yox olduqda, SwiftUI Structured Concurrency mexanizmi vasitəsilə Task-ı avtomatik ləğv edir — bu, asinxron əməliyyatın nəticəsi artıq heç kəsə lazım olmadıqdan sonra davam etməyəcəyinə zəmanət verir.

Apple — Swift Programming Language (2025) məlumatına görə, .task Swift 5.5-də təqdim edilmiş Structured Concurrency konsepsiyasından istifadə edir. Hər bir .task valideyn View tapşırığı çərçivəsində uşaq tapşırığı yaradır. Valideyn tapşırığı ləğv edilərsə (View yox olarsa), bütün uşaq tapşırıqları da avtomatik ləğv edilir. Bu, DispatchWorkItem və ya AnyCancellable istinadlarının əl ilə saxlanması ilə müqayisədə asinxron əməliyyatların həyat dövrünün idarə edilməsini kökündən asanlaşdırır.

@State + .onAppear-da əl ilə çağırma ənənəvi yanaşmasından fərqli olaraq, .task sonradan ləğv etmək üçün Task istinadının saxlanmasını tələb etmir. SwiftUI bunu avtomatik edir, bu da boilerplate kodun miqdarını azaldır və tapşırığı ləğv etməyi unutma riskini aradan qaldırır.

swift
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
            }
        }
    }
}

.task vs .onAppear: əsas fərqlər

Bir çox tərtibatçı məlumatları .onAppear-da yükləməyə öyrəşib, lakin async/await və .task-in meydana çıxması ilə bu yanaşma köhnəlmişdir. .onAppear kodu sinxron şəkildə yerinə yetirir — .onAppear daxilində asinxron əməliyyatlar üçün çağırışı Task { } ilə bükmək və mümkün ləğv üçün ona əl ilə istinad saxlamaq lazımdır. .task bunu avtomatik edir.

Xüsusiyyət.task { }.onAppear
Async kontekstiDaxili async/awaitTask { } bükməsi tələb olunur
AvtoləğvBəli, View yox olduqdaXeyr, əl ilə həyata keçirilməlidir
Structured ConcurrencyDəstəkləyirDəstəkləmir
Təkrar işə salmaYalnız id dəyişdikdəHər görünmədə
Apple tövsiyəsiÜstünlük verilən üsulSinxron əməliyyatlar üçün

.onAppear hələ də sinxron əməliyyatlar üçün faydalıdır — məsələn, loglama və ya UI-nin ilkin konfiqurasiyası. Lakin asinxron məlumat yükləmə, şəbəkə sorğuları, verilənlər bazası və ya fayl sistemi ilə iş üçün .task istifadə edin. Bu, arxitektura baxımından daha təhlükəsiz və təmizdir.

swift
// ❌ Köhnə yanaşma: .onAppear-da ləğv olmadan Task
var loadTask: Task<Void, Never>?
func body() { var body: some View { Text("") }
    .onAppear {
        loadTask = Task { await loadData() }
    }
    .onDisappear { loadTask?.cancel() }

// ✅ Müasir yanaşma: .task ləğvi idarə edir
func body() { var body: some View { Text("") }
    .task { await loadData() }

.task(id:) — məlumat dəyişdikdə yenidən işə salma

.task(id:) modifieri əlavə parametr — identifikator qəbul edir. Identifikatorun dəyəri dəyişdikdə, SwiftUI cari tapşırığı ləğv edir və yeni identifikatorla yenisini işə salır. Bu, məlumatların seçilmiş parametrdən asılı olduğu ekranlar üçün idealdır — məsələn, kateqoriya üzrə məqalələr siyahısı və ya ID üzrə məhsul təfərrüatları.

swift
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 {
            // xətanı idarə et
        }
    }
}

categoryId dəyişdikdə, SwiftUI əvvəlki sorğunu ləğv edir və yenisini işə salır. Bu, xüsusilə kateqoriyaların sürətli dəyişdirilməsi zamanı vacibdir — köhnə sorğular dövlət yeniləməsi üçün yeniləri ilə rəqabət aparmayacaq. .task(id:) olmadan, dəyişiklikləri .onChange vasitəsilə əl ilə izləmək və Task-ı əl ilə idarə etmək lazım gələrdi.

Tapşırıqların ləğvi və isCancelled yoxlanması

.task View yox olduqda tapşırığı avtomatik ləğv etsə də, asinxron əməliyyatın özü ləğvi kooperativ şəkildə yoxlamalıdır. Swift kooperativ ləğv modelindən istifadə edir — Task.cancel() icrasını məcburi dayandırmır, sadəcə isCancelled bayrağını təyin edir. Tapşırıq daxilindəki kod vaxtaşırı bu bayrağı yoxlamalıdır.

swift
struct LoadingView: View {
    @State var progress: Double = 0
    
    var body: some View {
        ProgressView(value: progress)
            .task {
                for i in 0..<100 {
                    // Ləğvi yoxla
                    try Task.checkCancellation()
                    
                    await Task.sleep(nanoseconds: 50_000_000)
                    progress = Double(i + 1) / 100.0
                }
            }
    }
}

Task.checkCancellation() tapşırıq ləğv edilibsə CancellationError atır. Bu yoxlamanın ən sadə üsuludur — istənilən async kontekstində işləyir. Alternativ — bahalı əməliyyatlardan əvvəl Task.isCancelled-ı əl ilə yoxlamaq. URLSession şəbəkə sorğuları tapşırıq ləğv edildikdə avtomatik ləğv olunur, çünki URLSession Structured Concurrency-ni əvvəldən dəstəkləyir.

.task üçün praktik nümunələr

.task sadə JSON yükləmədən TaskGroup ilə mürəkkəb paralel əməliyyatlara qədər bir çox ssenari üçün uyğundur. Üç tipik istifadə nümunəsinə baxaq.

Səhv idarəetməsi ilə yükləmə

swift
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("Yükləmək mümkün olmadı")
            }
        }
        .task {
            defer { isLoading = false }
            do {
                profile = await APIClient().fetchProfile()
            } catch {
                // profil nil qalır
            }
        }
    }
}

TaskGroup ilə paralel yükləmə

swift
struct DashboardView: View {
    @State var stats: DashboardStats?
    
    var body: some View {
        Text("İdarə 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
            }
    }
}

.task ilə tipik səhvlər

Ən çox yayılmış səhv — əsas mövzuya keçmədən .task daxilində UI xüsusiyyətlərini mutasiya etməkdir. SwiftUI async kontekstində @State dəyişdikdə yeniləmələri avtomatik əsas mövzuya qaytarsa da, .task daxilində UIKit elementləri ilə birbaşa manipulyasiyalar crash-a səbəb ola bilər.

  • try/catch unutdun — .task səhvləri avtomatik idarə etmir. Daxildəki bütün atma funksiyaları do/catch ilə bükülməlidir, əks halda tətbiq çökəcək.
  • Race condition — bir neçə .task(id:) müxtəlif id-lərlə işə salınıbsa və eyni dövləti yeniləyirsə, yarışlar mümkündür. Müxtəlif məlumat mənbələri üçün ayrıca xüsusiyyətlərdən istifadə edin.
  • Uzun sinxron əməliyyatlar — .task sinxron kodu asinxron etmir. .task daxilində ağır sinxron iş varsa, onu Task.detached ilə bükün və ya ayrıca async metoduna köçürün.
  • CancellationError-ı görməməzlik — Task.checkCancellation() yoxlanarkən CancellationError xətası yuxarı ötürülməlidir, basdırılmamalıdır. Ləğvin basdırılması yaddaş sızmasına səbəb ola bilər.
swift
// ❌ Xəta: xəta idarəetməsi yoxdur
.task {
    let data = await fetchData() // xətada çökür!
    items = data
}

// ✅ Düzgün: do/catch
.task {
    do {
        items = await fetchData()
    } catch {
        errorMessage = error.localizedDescription
    }
}

Tez-tez verilən suallar

.task və .onAppear-da Task { } istifadəsi arasında fərq nədir?

.task View yox olduqda tapşırığı avtomatik ləğv edir və Structured Concurrency dəstəkləyir. .onAppear-da Task { } tapşırığa əl ilə istinad saxlanmasını və .onDisappear-da cancel() çağırılmasını tələb edir. .task həmçinin oxumaq daha asandır — məlumat yükləməsinin View-in həyat dövrünün bir hissəsi olduğunu açıqca göstərir.

.task-i publisher-a abunə olmaq üçün istifadə etmək olarmı?

Bəli, AsyncSequence və ya AsyncStream-ə abunə olmaq üçün .task daxilində for await value in publisher.values istifadə edin. Bu həm async/await, həm də Publisher.values genişlənməsi vasitəsilə Combine ilə işləyir. View yox olduqda iterasiya avtomatik bitəcək və abunə ləğv ediləcək.

.task TabView ilə necə işləyir — vərəqlər dəyişdiriləndə tapşırıq yenidən işə salınırmı?

Bəli, TabView daxilindəki View hər dəyişmədə yenidən yaradılırsa. iOS 18-dən etibarən TabView View-i yaddaşda saxlaya bilər — bu halda .task təkrar işə salınmır. Hər dəyişmədə məlumatları yenidən yükləmək lazımdırsa, vərəq identifikatoru ilə .task(id:) istifadə edin.

.task olan View sorğu bitməmiş yox olarsa nə baş verir?

SwiftUI View yox olduqda tapşırığı ləğv edir. URLSession sorğusu tapşırıq daxilində idisə, o da ləğv ediləcək. Tapşırıq kooperativ ləğvi dəstəkləmirsə (məsələn, isCancelled yoxlamırsa), icra davam edəcək, lakin nəticəsi dövlətə tətbiq edilməyəcək, çünki View artıq mövcud deyil.

Bir View-də bir neçə .task istifadə etmək olarmı?

Bəli, bir View-ə bir neçə .task modifieri əlavə etmək olar. Hər biri müstəqil tapşırıq yaradır. Bu, müxtəlif məlumat mənbələrini ayırmaq üçün rahatdır: biri profil yükləmək, ikincisi WebSocket-ə abunə olmaq, üçüncüsü geolokasiyanı izləmək üçün.

Xülasə

  • .task { } — View yox olduqda avtoləğv ilə asinxron əməliyyatlar üçün SwiftUI modifieri.
  • async/await dəstəyi — .task daxilində Task bükməsi olmadan tam async konteksti mövcuddur.
  • .task(id:) — identifikator dəyişdikdə tapşırığı yenidən işə salır, əl ilə .onChange-i əvəz edir.
  • Kooperativ ləğv — tapşırıq daxilində ləğvi yoxlamaq üçün Task.checkCancellation() istifadə edin.
  • Structured Concurrency — .task TaskGroup və uşaq tapşırıqlarının ləğvi ilə paralel əməliyyatları dəstəkləyir.
  • .onAppear-ı əvəz etmə — asinxron məlumat yükləmə üçün .onAppear + Task + .onDisappear kombinasiyası əvəzinə .task istifadə edin.
  • Səhv idarəetməsi — .task daxilindəki bütün async çağırışları crash-in qarşısını almaq üçün do/catch ilə bükülməlidir.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun