Назад к вопросам
Middle
83
questionbank

В чем заключается отличие между Wick-ссылками и Anound-ссылками?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Wick-ссылка (weak) — это невладеющая ссылка. Она не увеличивает счетчик ссылок объекта. Используется для предотвращения циклов сильных ссылок, например, между делегатом и его владельцем. Если объект, на который указывает слабая ссылка, деаллоцируется, слабая ссылка автоматически становится nil.

Unowned-ссылка (unowned) — это также невладеющая ссылка и не увеличивает счетчик ссылок объекта. Отличие от weak в том, что unowned не может быть опционалом (Optional) и всегда должна указывать на существующий объект. Если объект, на который указывает unowned ссылка, деаллоцируется до того, как ссылка перестанет существовать, попытка доступа к этой ссылке приведет к ошибке выполнения (fatal error). Используется там, где жизненный цикл связанного объекта гарантированно дольше или равен жизненному циклу объекта с unowned-ссылкой (например, цикл сильных ссылок, где один из объектов имеет четко определенный жизненный цикл).

Сравнение:

Особенность weak unowned
Невладеющая Да Да
Увеличивает SC Нет Нет
Может быть nil Да (автоматически обнуляется) Нет (должна указывать на объект)
Безопасность Более безопасна при возможном деаллоцировании Менее безопасна (фатальная ошибка при доступе к деаллоцированному)
Тип Должна быть optional Не может быть optional (по умолчанию)
Использование Предотвращение циклов сильных ссылок, где объект может перестать существовать раньше Предотвращение циклов сильных ссылок, где объект гарантированно существует

Пример использования weak для предотвращения цикла сильных ссылок:

class Person {
    let name: String
    weak var apartment: Apartment? // weak reference to avoid retain cycle

    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

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

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) is being initialized")
    }

    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

Пример использования unowned в контексте захвата self в замыкании:

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

    lazy var asHTML: () -> String = {
        [unowned self] in // unowned self to avoid retain cycle with closure
        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) is being deinitialized")
    }
}