@EnvironmentObject — bu nədir, iş prinsipi və istifadəsi

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

@EnvironmentObject — SwiftUI-də property wrapper-dır, ObservableObject-i açıq şəkildə initilizatora ötürmədən bütün view iyerarxiyası vasitəsilə avtomatik ötürür. Uşaq view şəkildə obyektə sadəcə xassə elan etməklə çevrə mühiti obyektinə çıxış əldə edir, valideyn isə onu .environmentObject() metodu ilə təmin edir. Apple Developer Documentation (2025) məlumatlarına görə, SwiftUI çevrə mühiti səviyyəsində asılılıq inyeksiyası mexanizmindən istifadə edir ki, bu da ara view konstruktorları vasitəsilə məlumatları ötürmək ehtiyacını aradan qaldırır. @EnvironmentObject xüsusilə tətbiqin bir çox ekranında tələb olunan obyektlər üçün faydalıdır — autentifikasiya modelləri, alış-veriş səbətləri və ya qlobal parametrlər.

Əsas məqamlar

  • @EnvironmentObject — SwiftUI çevrə mühitindən ObservableObject-i initilizator vasitəsilə ötürmədən əldə edən property wrapper
  • Inyeksiya valideyn view-də .environmentObject() metodu ilə həyata keçirilir — obyekt bütün uşaq elementlər üçün əlçatan olur
  • Fərqi @ObservedObject-dən: uşaq view-lər initilizatorda parametr tələb etmir, obyekt avtomatik olaraq tipinə görə götürülür
  • Səhv çevrə mühitində obyektin olmaması — tətbiqin fatal error ilə çökməsi, buna görə obyekt ilk uşaq view-dən əvvəl təmin edilməlidir
  • iOS 17+ @Observable makrosu qismən ObservableObject-i əvəz edir, lakin @EnvironmentObject yeni makro ilə @Environment vasitəsilə işləməyə davam edir

@EnvironmentObject nədir?

@EnvironmentObject — SwiftUI çərçivəsində elan edilmiş property wrapper-dır, view-ə çevrə mühitində saxlanılan obyektə çıxış imkanı verir. @State və ya @StateObject-dən fərqli olaraq, @EnvironmentObject obyekt yaratmır — o, yalnız view iyerarxiyasında əcdadlardan biri tərəfindən təmin edilmiş mövcud instansiyanı oxuyur.

İş mexanizmi SwiftUI çevrə mühitinə — kök view-dən bütün uşaqlara ötürülən qeyri-açıq lüğətə əsaslanır. Valideyn .environmentObject(someObject) metodunu çağırdıqda, SwiftUI someObject-ə istinadı çevrə mühitinə yerləşdirir. Alt ağacdakı istənilən view @EnvironmentObject var model: ViewModel elan edə və eyni instansiyanı əldə edə bilər.

Apple WWDC 2021 “Demystify SwiftUI” sessiyasına görə, çevrə mühiti dərin iyerarxiya vasitəsilə performans itkisi olmadan məlumat ötürmək üçün optimallaşdırılıb — obyektə giriş tip üzrə axtarış vasitəsilə O(1) ilə həyata keçirilir. Bu, mürəkkəbliyin iyerarxiya dərinliyi ilə xətti artdığı konstruktorlar vasitəsilə əl ilə ötürmədən fərqlənir.

Tətbiqin müxtəlif səviyyələrində tələb olunan qlobal vəziyyət üçün @EnvironmentObject istifadə edin. Tipik namizədlər — autentifikasiya modelləri, naviqasiya menecerləri, alış-veriş səbətləri və şəbəkə məlumat təminatçıları.

@EnvironmentObject necə işləyir

@EnvironmentObject SwiftUI-nin çevrə mühitinə əsaslanan asılılıq inyeksiyası adlı mexanizmindən istifadə edir. SwiftUI iyerarxiyanı render edərkən, hər səviyyədə oxunub yazıla bilən daxili EnvironmentValues lüğətini saxlayır. @EnvironmentObject property wrapper-i dəyişikliklərə abunə olmaq üçün ObservableObject protokolundan objectWillChange istifadə edərək bu lüğətdən obyekti tipinə görə oxuyur.

Proses üç addımdan ibarətdir. Birinci — iyerarxiyada haradasa ObservableObject yaratmaq, adətən valideyn view-də @StateObject və ya @ObservedObject vasitəsilə. İkinci — bu view-də .environmentObject(object) çağırmaq, obyekti çevrə mühitinə yerləşdirir. Üçüncü — uşaq view-lərdə @EnvironmentObject elan etmək, onlar avtomatik olaraq eyni instansiyanı alır və abunə olurlar.

SwiftUI zəmanət verir ki, obyekt daxilində istənilən @Published xassəsi hər dəfə dəyişdikdə, bu tiplə @EnvironmentObject elan etmiş bütün view-lər yenidən çəkiləcək. Donni Uolsa görə (Donny Wals, 2024), abunə mexanizmi @ObservedObject ilə eynidir — fərq yalnız instansiyanın əldə edilmə üsulundadır, yenilənmə mexanizmində deyil.

İyerarxiyanı elə qurun ki, obyekt mümkün qədər yüksəkdə təmin edilsin — bu, kodu təkrarlamadan ehtiyacı olan bütün view-lər üçün çıxışı təmin edəcək.

@EnvironmentObject vs @ObservedObject

Hər iki property wrapper — @EnvironmentObject@ObservedObject — ObservableObject-ə abunə olur və dəyişikliklər zamanı view-i yenidən çəkir. Əsas fərq obyektin əldə edilmə üsulundadır. @ObservedObject instansiyanın view-in initilizatoru vasitəsilə açıq ötürülməsini tələb edir, @EnvironmentObject isə onu avtomatik olaraq çevrə mühitindən alır.

Üç səviyyəli iyerarxiyanı nəzərdən keçirək: ParentView → MiddleView → ChildView. Əgər ChildView-ə UserSettings obyekti lazımdırsa, @ObservedObject istifadə edərkən onu MiddleView vasitəsilə ötürmək lazım gələcək, hətta MiddleView bu obyektdən istifadə etməsə belə:

swift
struct MiddleView: View {
    @ObservedObject var settings: UserSettings  // yalnız aşağı ötürmək üçün lazımdır

    var body: some View {
        ChildView(settings: settings)
    }
}

@EnvironmentObject ilə MiddleView obyektin mövcudluğu haqqında bilmək məcburiyyətində deyil:

swift
struct MiddleView: View {
    var body: some View {
        ChildView()
    }
}

struct ChildView: View {
    @EnvironmentObject var settings: UserSettings

    var body: some View {
        Text(settings.username)
    }
}

Swift by Sundell (2024) məlumatlarına görə, @EnvironmentObject obyekt iyerarxiyanın bir neçə səviyyəsində tələb olunduqda üstünlük təşkil edir, @ObservedObject isə obyekt valideyndən yeganə birbaşa uşağa ötürüldükdə üstünlük təşkil edir. Yerli, birdəfəlik ötürmələr üçün @ObservedObject, qlobal asılılıqlar üçün isə @EnvironmentObject seçin.

@EnvironmentObject vs @Environment

@Environment@EnvironmentObject — hər ikisi SwiftUI çevrə mühitindən məlumat oxuyur, lakin müxtəlif mənbələrlə işləyir. @Environment EnvironmentValues-dən daxili və ya xüsusi dəyərləri oxuyur — bunlar sadə məlumatlardır: rənglər, şriftlər, ölçülər, təqvim, layoutDirection. @EnvironmentObject ObservableObject-ə uyğun istinad tiplərini oxuyur.

Əsas fərq — yenilənmə mexanizmi. @Environment fərdi dəyərlər səviyyəsində publish-subscribe istifadə edir: çevrə mühiti dəyişdikdə yalnız həmin dəyəri oxuyan view-lər yenidən çəkilir. @EnvironmentObject ObservableObject-in objectWillChange-inə abunə olur ki, bu da hansı xassənin dəyişdiyindən asılı olmayaraq bu tipə abunə olmuş bütün view-lərin yenidən çəkilməsinə səbəb ola bilər.

Hacking with Swift (Paul Hudson, 2025) məlumatlarına görə, @Environment konfiqurasiya parametrləri üçün uyğundur: rəng sxemi, dinamik şrift ölçüsü, cihazın oriyentasiyası. @EnvironmentObject — biznes məntiqi və vəziyyət üçün: məlumat modelləri, xidmətlər, menecerlər. Statik və ya nadir dəyişən parametrlər üçün @Environment, reaktivlik tələb edən dinamik məlumatlar üçün isə @EnvironmentObject istifadə edin.

Praktikada bu iki mexanizm tez-tez birləşdirilir: @EnvironmentObject məlumat verir, @Environment isə göstərmə kontekstini təmin edir.

@EnvironmentObject istifadəsində tipik səhvlər

Ən geniş yayılmış səhv — ona müraciət edərkən çevrə mühitində obyektin olmaması. Əgər view @EnvironmentObject var model: ViewModel elan edibsə, lakin heç bir əcdad .environmentObject(model) çağırmayıbsa, SwiftUI “No ObservableObject of type ViewModel found” mesajı ilə fatal error atacaq. Bu, render mərhələsində baş verir, kompilasiya zamanı deyil, buna görə səhv yalnız icra zamanı üzə çıxa bilər.

İkinci geniş yayılmış problem — eyni tipin çoxsaylı instansiyaları. SwiftUI çevrə mühitində axtarış üçün obyektin tipindən açar olaraq istifadə edir. Əgər iki fərqli əcdad .environmentObject vasitəsilə ViewModel-in fərqli instansiyalarını təmin edibsə, uşaq view iyerarxiyada ən yaxın olanı alacaq ki, bu da gözlənilən davranışa səbəb ola bilər. Həll — hər tipin çevrə mühitində dəqiq bir dəfə olmasını təmin etmək.

Üçüncü səhv — yalnız bir-iki view-ə lazım olan məlumatlar üçün @EnvironmentObject-dən həddindən artıq istifadə. Bu halda @ObservedObject initilizator vasitƏlə açıq ötürmƉ ilə daha şəffaf məlumat axını təmin edir və testi asanlaşdırır. Point-Free (2025) məlumatlarına görə, çevrə mühitində həddindən artıq çox obyekt view asılılıqlarını anlamağı çətinləşdirir və kodu daha az proqnozlaşdırıla bilən edir.

Hər @EnvironmentObject-in iyerarxiyanın düzgün səviyyƉsindƉ təmin edildiyini yoxlayın və erkən mərhƉlƉdƉ çatışmazlığı aşkar etmək üçün kritik obyektlər üçün onAppear-də fallback yoxlamaları əlavə edin.

@EnvironmentObject ilə kod nümunələri

Qlobal autentifikasiya vəziyyəti olan tam tətbiq nümunəsini nəzərdən keçirək. İstifadəçinin giriş vəziyyətini saxlayan ObservableObject AuthManager yaradaq və onu @EnvironmentObject vasitəsilə bütün ekranlara təmin edək:

swift
import SwiftUI
import Combine

class AuthManager: ObservableObject {
    @Published var isLoggedIn = false
    @Published var username: String = ""

    func login(user: String) {
        username = user
        isLoggedIn = true
    }

    func logout() {
        username = ""
        isLoggedIn = false
    }
}

Kök view AuthManager-i çevrə mühiti vasitəsilə təmin edir:

swift
@main
struct MyApp: App {
    @StateObject private var authManager = AuthManager()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(authManager)
        }
    }
}

Uşaq view AuthManager-i açıq ötürmə olmadan alır:

swift
struct ProfileView: View {
    @EnvironmentObject var authManager: AuthManager

    var body: some View {
        VStack {
            if authManager.isLoggedIn {
                Text("Hello, \(authManager.username)")
                Button("Hesabdan çıx") {
                    authManager.logout()
                }
            } else {
                Button("Daxil ol") {
                    authManager.login(user: "user")
                }
            }
        }
    }
}

Üçüncü nümunə — bir neçə ObservableObject və @EnvironmentObject ilə @Environment-in birləşdirilməsi. Tətbiqin alış-veriş səbəti üçün CartManager və rəng sxemi üçün ThemeManager istifadə etdiyini fərz edək. Hər ikisi yuxarı səviyyədə təmin edilir və initilizatorlar vasitƏlə ötürmədən istənilən ekranda əlçatandır. Bu, xüsusilə ekranların dərin yerləşdirilməsi və ya məlumatların konstruktor vasitƏlə ötürməsinin texniki cəhətdən çətin olduğu modal view-lərin istifadəsi zamanı rahatlıq yaradır.

Tez-tez verilən suallar

@EnvironmentObject @ObservedObject-dən nə ilə fərqlənir?

@ObservedObject instansiyanın view-in initilizatoru vasitəsilə açıq ötürülməsini tələb edir, @EnvironmentObject isə obyekti avtomatik olaraq SwiftUI çevrə mühitindən alır. @EnvironmentObject iyerarxiyanın bir neçə səviyyəsində tələb olunan məlumatlar üçün rahatdır, @ObservedObject isə valideyn və uşaq arasında birbaşa ötürmə üçün üstünlük təşkil edir.

@EnvironmentObject təmin edilməsə nə baş verər?

SwiftUI icra zamanı fatal error atacaq: “No ObservableObject of type X found”. Səhv @EnvironmentObject elan etmiş view-in render edilməsi anında baş verir, əgər heç bir əcdad bu tipli obyektlə .environmentObject() çağırmayıbsa. Kompilator bu vəziyyət barədə xəbərdarlıq etməz.

@EnvironmentObject iOS 13 ilə istifadə edilə bilərmi?

Bəli, @EnvironmentObject iOS 13.0, macOS 10.15, tvOS 13.0 və watchOS 6.0-dan etibarən mövcuddur. Bu, Apple tərəfindən 2019-cu ildə SwiftUI ilə birlikdə təqdim edilmiş ilk property wrapper-lardan biridir və @Observable makrosu ilə iOS 17 və 18 də daxil olmaqla bütün sonrakı versiyalarda işləyir.

@EnvironmentObject vasitəsilə neçə obyekt ötürülə bilər?

Obyektlərin sayı məhdud deyil — hər tip unikal açar rolunu oynayır. AuthManager, CartManager, NavigationManager və digər xidmətləri hər biri üçün ayrıca .environmentObject() çağırmaqla ötürmək olar. Çevrə mühitində eyni tipli iki obyektin olmaması vacibdir — bu, qeyri-müəyyən davranışa səbəb olar.

@EnvironmentObject ilə view-i necə test etmək olar?

Testlərdə ObservableObject instansiyası yaradın və onu Preview Provider və ya XCTest-də .environmentObject(obj) vasitəsilə ötürün. View-in vahid testləri üçün konkret sinif əvəzinə protokol istifadə etmək rahatdır — bu, real iyerarxiyanı dəyişmədən asılılıqları mock-obyektlərlə əvəz etməyə imkan verir.

Nəticə

  • @EnvironmentObject — SwiftUI çevrə mühitindən ObservableObject-i initilizator vasitəsilə ötürmədən avtomatik əldə etmək üçün property wrapper
  • Mexanizm çevrə mühitinə əsaslanan asılılıq inyeksiyasına əsaslanır: obyekt .environmentObject() metodu ilə çevrə mühitinə yerləşdirilir və tip üzrə çıxarılır
  • Fərqi @ObservedObject-dən: @EnvironmentObject ara view-ləri dərin uşaqların asılılıqlarını bilmək məcburiyyətindən azad edir
  • Fərqi @Environment-dən: @EnvironmentObject ObservableObject ilə işləyir, @Environment — EnvironmentValues dəyərləri ilə
  • Riskli məsələlər: çevrə mühitində obyekt olmadıqda fatal error, eyni tipin çoxsaylı instansiyaları problemi, qlobal vəziyyətdən sui-istifadə
  • iOS 17+ @Observable makrosu @EnvironmentObject-i ləğv etmir — hər iki mexanizm müxtəlif ssenarilər üçün mövcuddur
  • Best practice: obyektləri iyerarxiyanın mümkün qədər yüksək səviyyəsində təmin edin, qlobal xidmətlər üçün @EnvironmentObject, lokal ötürmələr üçün @ObservedObject istifadə edin

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