Что работает быстрее: weak или unowned ссылка в Swift?

Ответ

С точки зрения производительности unowned ссылка теоретически быстрее, но разница настолько ничтожна, что выбор должен основываться на семантике жизненного цикла объектов, а не на скорости.

Сравнение:

Критерий weak unowned
Тип Опциональная ссылка (T?) Неопциональная ссылка (T)
Поведение Автоматически становится nil при освобождении объекта. Не становится nil; обращение к освобожденному объекту вызывает краш (dangling pointer).
Накладные расходы Требует проверки на nil при разыменовании и механизма zeroing weak ref. Не требует проверки, работает почти как обычная ссылка.
Использование Когда ссылаемый объект может быть освобожден раньше. Когда ссылаемый объект гарантированно живет не меньше, чем ссылающийся (например, дочерний объект, который не переживает родительский).

Пример выбора:

// weak: ViewController может быть освобожден, пока сетевой запрос выполняется
apiService.fetchData { [weak self] result in
    self?.handle(result) // Безопасно, self может быть nil
}

// unowned: CreditCard не может существовать без Customer
class Customer {
    var card: CreditCard?
}
class CreditCard {
    unowned let owner: Customer // owner всегда будет существовать, пока существует card
    init(owner: Customer) { self.owner = owner }
}

Вывод: Всегда выбирайте weak для безопасности, если есть сомнения в жизненном цикле. Используйте unowned только при абсолютной уверенности, что объект «переживет» ссылку, — это микрооптимизация, оправданная лишь в очень редких, критичных к производительности сценариях.

Ответ 18+ 🔞

Да ты послушай, какой тут у нас цирк с конями развели про weak и unowned! Говорят, мол, unowned быстрее, ёпта. Ну да, быстрее, как хуй с горы — теоретически-то да, но на практике эта разница такая, что её только электронный микроскоп разглядит, а ты тут сидишь и думаешь, какую же ссылку выбрать, чтобы не обосраться.

Вот смотри, табличку для особо одарённых нарисовали, чтобы не путались:

По чём бьём weak unowned
Что за зверь Ссылка-недотрога (T?), может и сбежать в nil. Ссылка-самоубийца (T), упёртая, как манда с ушами.
Как себя ведёт Объект освободили — ссылка сама в nil превратилась, умница. Объект освободили, а ты по старой памяти лезешь — получаешь краш, dangling pointer и сеанс психотерапии.
Что жрёт Чуть-чуть жрёт на проверки, да нуль-реф механизм. Почти ничего не жрёт, работает как обычная, наивная дура.
Когда тыкать Когда твой объект может внезапно испариться, пока ты моргнул. Только когда ты на 146% уверен, что один объект не переживёт другой.

Пример, чтобы въехало:

// weak: Контроллер может в любой момент накрыться медным тазом, пока запрос идёт
apiService.fetchData { [weak self] result in
    self?.handle(result) // Спокойно, self может быть уже nil, и ничего не взорвётся
}

// unowned: Карта кредитная без владельца — это пиздец какой-то, а не карта
class Customer {
    var card: CreditCard?
}
class CreditCard {
    unowned let owner: Customer // Владелец гарантированно жив, пока карта существует. Иначе это уже мошенничество.
    init(owner: Customer) { self.owner = owner }
}

Итог, блядь, простой, как три копейки: если у тебя в голове хоть капля сомнения, кто кого переживёт — жми weak и спи спокойно. unowned — это для тех редких случаев, когда ты архитектор от бога и жизненный цикл объектов у тебя прописан, как в военном уставе. Гнаться за этой микроскопической производительностью — всё равно что ебаться из-за копейки, рискуя получить в жопу. Выбор за тобой, чувак.