Sobes.tech
Middle

У чему се састоји разлика између Wick-линкова и Anound-линкова?

sobes.tech АИ

Одговор од АИ

Wick-povezanost (weak) — то је невласничка референца. Она не повећава број референци на објекат. Користи се за спречавање циклуса јаких референци, на пример, између делегата и његовог власника. Ако објекат на који указује слабa референца буде деалокиран, слабa референца аутоматски постаје nil.

Unowned-референца (unowned) — такође је невласничка референца и не повећава број референци на објекат. Разлика од weak је у томе што unowned не може бити опционална (Optional) и увек мора да указује на постојећи објекат. Ако објекат на који указује unowned референца буде деалокиран пре него што референца престане да постоји, покушај приступа тој референци довешће до грешке при извршавању (фатална грешка). Користи се тамо где је животни циклус повезаног објекта гарантовано дужи или једнак животном циклусу објекта са unowned-референцом (на пример, циклус јаких референци, где један од објеката има јасно дефинисан животни циклус).

Поређење:

Карактеристика weak unowned
Невласничка Да Да
Повећава SC Не Не
Може бити nil Да (аутоматски нулирано) Не (мора да указује на објекат)
Безбедност Безбедније при могућем деалокирању Мање безбедно (фатална грешка при приступу деалокираном)
Тип Мора бити опционално Не може бити опционално (по подразумевано)
Коришћење Предотврђивање циклуса јаких референци, где објекат може престати да постоји раније Предотврђивање циклуса јаких референци, где је објекат гарантовано постојећи

Пример коришћења weak за спречавање циклуса јаких референци:

class Person {
    let name: String
    weak var apartment: Apartment? // слабa референца за избегавање циклуса

    init(name: String) {
        self.name = name
        print("\(name) је иницијализован")
    }

    deinit {
        print("\(name) је деинициализован")
    }
}

class Apartment {
    let unit: String
    var occupant: Person?

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) је иницијализован")
    }

    deinit {
        print("Apartment \(unit) је деинициализован")
    }
}

Пример коришћења unowned у контексту хватања self у затварању:

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        [unowned self] in // unowned self за избегавање циклуса задржавања са затварањем
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) је деинициализован")
    }
}