Ответ
С точки зрения производительности 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 — это для тех редких случаев, когда ты архитектор от бога и жизненный цикл объектов у тебя прописан, как в военном уставе. Гнаться за этой микроскопической производительностью — всё равно что ебаться из-за копейки, рискуя получить в жопу. Выбор за тобой, чувак.