Unowned Reference: nədir, sintaksisi və tətbiqi mobil tətbiqlərdə

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

Unowned Reference (sahibsiz referans) — Swift-də retain count-u artırmayan və weak-dən fərqli olaraq, obyekt azad edildikdən sonra nil-ə təyin edilməyən sahib olmayan bir referansdır. Apple Swift Language Guide, 2026-ya görə, unowned obyektin ən azı ona istinad edən obyekt qədər yaşayacağı təmin edildikdə tətbiq edilir. Weak Reference-dən fərqli olaraq, unowned unwrap tələb etmir — bu non-optional tipdir, kodu daha təmiz edir, lakin proqramçıya həyat müddəti zəmanəti üçün məsuliyyət qoyur.

Əsas məqamlar

  • Unowned Reference — avtomatik sıfırlanmayan sahib olmayan referans; non-optional, retain count-u artırmaz
  • Zəmanət — obyektin istinad edən obyektdən əvvəl azad edilə bilməyəcəyi təmin edildikdə tətbiq edilir
  • Weak-dən fərqi — unowned nil-ə sıfırlanmır (crash riski), weak sıfırlanır (təhlükəsiz)
  • Ssenarilər — həyat zəmanəti olan parent-child, unowned self ilə klemenslər, sinqletonlar və Service Locator
  • Risk — azad edilmiş unowned obyektinə müraciət runtime crash-a səbəb olur (EXC_BAD_ACCESS)

Unowned Reference nədir?

Unowned Reference — ARC-də retain count-u artırmayan sahib olmayan bir obyekt referansıdır. Weak-dən fərqli olaraq, unowned deallokasiyadan sonra sıfırlanmır: o, artıq azad edilmiş yaddaş sahəsinə işarə etməyə davam edir. Belə bir referansa müraciət EXC_BAD_ACCESS ilə runtime crash-a səbəb olur.

“Sahibsiz” termini semantikanı əks etdirir: obyekt mövcuddur, lakin heç kim onun həyat müddətinə cavabdeh deyil. Proqramçı açıq şəkildə bəyan edir: “Mən zəmanət verirəm ki, bu obyekt mən ona istinad edərkən yaşayacaq”. Kompilyator bu zəmanəti yoxlamır — bu, proqramçı səviyyəsində kontraktdır.

Swift.org Documentation, 2026-ya görə, unowned referanslar zəmanətli həyat müddəti olan ssenarilərdə weak-dən üstündür, çünki: onlar opsional tip tələb etmir (təmiz kod), unwrap tələb etmir (daha az force-unwrap və ya guard let) və zeroing weak-cədvəlinin saxlanması üçün əlavə yük daşımır. Lakin kontraktın hər hansı pozulması — crash deməkdir.

Swift-də unowned sintaksisi

Swift-də unowned referanslar let və ya var qarşısında unowned açar sözü ilə bəyan edilir. Weak-dən fərqli olaraq, unowned həm let, həm də var ola bilər və opsional tip tələb etmir. Bu xüsusiyyət unowned-ı mövzu sahəsinin məntiqinə görə nil ola bilməyən referanslar üçün əlverişli edir.

swift
class Country {
    let name: String
    var capital: City!           // iniziasiyadan sonra təyin ediləcək
    init(name: String) { self.name = name }
}

class City {
    let name: String
    unowned let country: Country   // ✅ unowned let — həyat zəmanəti

    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

// İstifadə
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// ✅ Country → City (strong), City → Country (unowned) — retain cycle yoxdur

Bu nümunədə City unowned let country — şəhər ölkə olmadan mövcud ola bilməz. Ölkə yox olsa, şəhər (və referans) mənasını itirər. Semantik olaraq bu unowned üçün ideal haldır: həyat müddəti zəmanəti var, optional lazım deyil, retain cycle yaranmır.

unowned var

unowned var icazəlidir, lakin daha az rast gəlinir. Referansın dəyişdirilə biləcəyi hallarda istifadə olunur (məsələn, uşağın başqa valideynə bağlanması). Dəyişiklik zamanı köhnə obyektin azad edilməsi — xarici sahibin məsuliyyətidir.

Unowned Optional

Swift 5.0+-da unowned optional dəstəklənməyə başladı (unowned let x: Type?). Bu kompromisdir: unowned zəmanət verir ki, referans nil deyilsə, obyekt yaşayır. Azad edilmə zamanı davranış — adi unowned kimi crash-dır.

Unowned vs Weak: nə vaxt nəyi istifadə etməli

Unowned və weak arasında seçim — Swift arxitekturasını layihələndirərkən tez-tez verilən qərarlardan biridir. Hər bir hal üçün meyarları və tövsiyələri nəzərdən keçirək.

MeyarWeakUnowned
OptionalBəli (Type?)Xeyr (Type)
Deallokasiyada sıfırlamaAvtomatik nilXeyr (asılı göstərici riski)
Tip (let/var)Yalnız varlet və ya var
PerformansWeak-cədvəl üçün əlavə yükMinimal (sadə göstərici)
TəhlükəsizlikTəhlükəsiz (nil yoxlanılır)EXC_BAD_ACCESS riski
Həyat müddəti zəmanətiTələb olunmurAçıq zəmanət tələb olunur

Praktik qayda

Obyektin həyat müddəti ilə bağlı ən kiçik şübhə varsa, weak istifadə edin. Weak təhlükəsizdir, anlaşıqlıdır və sübut tələb etmir. Unowned istifadə edin yalnız obyektin daha tez azad edilə biləcəyi bütün ssenariləri istisna etdikdə. Tipik hallar: valideyn olmadan mövcud olmayan uşaq; sinxron icra olunan klemens; obyektin öz init metodunda istinad edilməsi.

Airbnb Swift Style Guide, 2025-ə görə, böyük kod bazalarında default olaraq weak istifadə etmək, unowned isə yalnız həyat müddəti zəmanətini izah edən açıq şərhlə istifadə etmək tövsiyə olunur. Bu, refaktoring zamanı gözlənilməz crash riskini azaldır.

Klemenslərdə unowned self

Klemenlər (closures) — parent-child münasibətlərindən sonra unowned-in ikinci ən çox istifadə ssenarisi. Capture list [unowned self] self-in klemensdən daha uzun yaşayacağı zəmanət edildikdə tətbiq edilir. Düzgün və səhv ssenariləri nəzərdən keçirək.

Unowned self nə vaxt təhlükəsizdir

Sinxron klemenlər — sorted, filter, map. Onlar dərhal cari thread-də icra olunur, self mütləq yaşayır. Unowned ilə capture list burada məqbuldur və daha təmiz kod verir.

swift
class DataProcessor {
    var items: [Int] = [3, 1, 4, 1, 5]

    func processSorted() {
        // ✅ unowned self — sorted sinxron icra olunur, self mütləq yaşayır
        let sorted = items.sorted { [unowned self] a, b in
            return self.customCompare(a, b)
        }
    }

    func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}

Unowned self nə vaxt təhlükəlidir

Asinxron klemenlər — gecikmə, şəbəkə sorğuları, animasiyalarla. Self klemensin yerləşdirilməsi və icrası arasında azad edilə bilər. Burada unowned self → crash. [weak self] istifadə edin.

swift
class NetworkLoader {
    func loadData() {
        // ❌ TƏHLÜKƏLİ: asinxron klemensdə unowned self
        URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
            self.handleResponse(data)  // CRASH self azad edilibsə
        }.resume()
    }

    func handleResponse(_ data: Data?) { }

    // ✅ DÜZGÜN: weak self + guard
    func loadDataSafe() {
        URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
            guard let self else { return }
            self.handleResponse(data)
        }.resume()
    }
}

Qaydanı xatırlayın: unowned self — yalnız dərhal icra olunan sinxron klemenlər üçün. Asinxron üçün — həmişə weak self + guard let. İstisna: obyektə referansı klemens tamamlanana qədər açıq şəkildə saxlayırsınızsa (məsələn, güclü tutmanı başqa dəyişəndə saxlamaqla).

Unowned riskləri və onlardan necə qaçınmaq

Unowned — güclü, lakin təhlükəli alətdir. Unowned-in crash-a səbəb ola biləcəyi real ssenariləri və risk mi-nimizasiya metodlarını nəzərdən keçirək.

Refaktoring və zəmanətlərin dəyişməsi

Əsas risk unowned — həyat müddəti zəmanətinin yerinə yetirilməsini dayandıran biznes məntiqinin dəyişməsidir. Proqramçı kodu refaktor edir: mülkiyyəti dəyişir, gecikdirilmiş azad etmə tətbiq edir, keşləmə əlavə edir — və unowned referansı gecikmiş bomba çevrilir. Kompilyator xəbərdarlıq etməyəcək — yalnız istifadəçi cihazında crash.

Tövsiyə: unowned yalnız həyat müddəti zəmanəti aşkar və sənədləşdirildikdə istifadə edin. Hər unowned-ə şərh əlavə edin: bu referans niyə təhlükəsizdir və hansı şərtlərdə pozula bilər.

UIKit iyerarxiyalarında unowned

UIKit — unowned üçün yüksək risk zonası. ViewController naviqasiya (pop, dismiss), yaddaşdan boşaltma, oriyentasiya dəyişikliyi zamanı istənilən anda azad edilə bilər. ViewController-ı unowned self ilə klemensə ötürsəniz — fondan qayıdarkən və ya animasiya bitdikdə self nil ola bilər.

Ən yaxşı təcrübələr

Unowned istifadə edərkən riski azaltmaq üçün bu qaydalara əməl edin:

  • Default olaraq weak-ə üstünlük verin — weak təhlükəsizdir, unowned optimallaşdırmadır, standart deyil
  • Zəmanətləri sənədləşdirin — hər unowned üçün əsaslandırma ilə şərh yazın
  • ViewController-də unowned-dən qaçın — UIKit həyat dövrü unowned zəmanətləri üçün proqnozlaşdırıla bilməz
  • Unowned yalnız sinxron klemenlər üçün istifadə edin — sorted, filter, map — təhlükəsiz namizədlər
  • Code review-də yoxlayın — hər unowned kod müəllifindən əsaslandırma tələb edir
  • Ən kiçik şübhədə weak-ə keçin — oxunaqlıq itkisi (bir guard let) istehsalatdakı crash-dan azdır
swift
// Nümunə: açıq əsaslandırma ilə sənədləşdirilmiş unowned referans
class InvoiceLineItem {
    let productName: String
    let price: Decimal

    // unowned Invoice — InvoiceLineItem Invoice olmadan mövcud ola bilməz.
    // Invoice Item yaradır və öz silinməsi zamanı onu silir.
    // Zəmanət: Invoice ən azı Item qədər yaşayır.
    unowned let invoice: Invoice

    init(productName: String, price: Decimal, invoice: Invoice) {
        self.productName = productName
        self.price = price
        self.invoice = invoice
    }
}

// Bu güclü zəmanətdir: Invoice deinit-də bütün Item-ləri silir.
// zəmanətin pozulması = düzəldilməli olan biznes məntiqi xətası.

Zəmanətlərin sənədləşdirilməsi — peşəkar standartdır. Böyük layihələrdə (Airbnb, Uber) code review hər unowned üçün əsaslandırma tələb edir. Zəmanət aşkar deyilsə — weak istifadə edin. Unowned-ə şərh gələcək proqramçılara burada niyə weak olmadığını və hansı şərtlərin zəmanəti poza biləcəyini anlamağa kömək edir.

Tez-tez verilən suallar

Obyekt azad edildikdən sonra unowned referansa müraciət etdikdə nə baş verir?

Runtime crash EXC_BAD_ACCESS ilə. Swift giriş zamanı unowned referansın düzgünlüyünü yoxlamır — bu sadəcə “xam” göstəricidir. Obyekt azad edilibsə, yaddaşın üzərinə yazılıb və ona müraciət qəzaya səbəb olur. Bu tutulmayan istisnadır (try-catch deyil).

Unowned protokollarla istifadə edilə bilərmi?

Bəli, protokol AnyObject-dən miras alırsa. Unowned bütün referans tipləri ilə işləyir: siniflər, AnyObject protokolları, Objective-C obyektləri. Dəyər tipləri (struct, enum) ARC-də iştirak etmədikləri üçün unowned-i dəstəkləmir.

Nə vaxt unowned weak-dən təhlükəsizdir?

Həyat müddəti zəmanəti mütləq və aşkar olduqda — unowned dizayn baxımından daha təhlükəsizdir: unwrap tələb etmir, nil ola bilməz, səhvləri gizlətmir. Obyekt valideyn olmadan mövcud ola bilmirsə, unowned bunu açıq kontrakt edir, weak isə zəmanəti bulandırır.

Unowned və weak arasında performans fərqi varmı?

Bəli: unowned daha sürətlidir, çünki sıfırlama üçün runtime weak-cədvəlinə giriş tələb etmir. Əksər tətbiqlərdə fərq hiss olunmur, lakin milyonlarla müraciət olan yüksək yüklü ssenarilərdə unowned oxuma zamanı 10–20% daha sürətli ola bilər.

Refaktoring unowned zəmanətlərinə necə təsir edir?

Refaktoring — unowned üçün əsas təhlükədir. Obyektin həyat müddətinin dəyişməsi (keşləmə, asinxron əməliyyatlar, təkrar istifadə) zəmanəti poza bilər. Kompilyator xəbərdarlıq etməyəcək. Həll yolu: arxitektura dəyişikliyində weak-ə keçin və ya xəbərdarlıq şərhi əlavə edin.

Xülasə

  • Unowned Reference — sıfırlanmayan sahib olmayan referans; non-optional, retain count-u artırmaz
  • Zəmanət — obyektin istinad edən koddan az yaşamadığına dair açıq sübut tələb edir
  • Sintaksisunowned let və ya unowned var; non-optional və optional ola bilər (Swift 5.0+)
  • Unowned vs Weak — unowned daha sürətli və təmizdir, lakin weak daha təhlükəsizdir; weak — default seçim
  • Klemenlər — unowned self yalnız sinxron klemenlər üçün; asinxron [weak self] tələb edir
  • Sənədləşdirmə — hər unowned zəmanətin əsaslandırması ilə şərhə malik olmalıdır
  • Tövsiyə — şübhə olduqda weak seçin; unowned — aşkar və sənədləşdirilmiş kontraktlar üçün

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