Ответ
Ключевой риск unowned — небезопасное разыменование. Это ссылка, которая не увеличивает счетчик ссылок (ARC) и не обнуляется автоматически (non-optional). Если объект, на который она указывает, будет освобожден, попытка доступа вызовет краш (EXC_BAD_ACCESS).
Сравнение weak vs unowned: |
Критерий | weak |
unowned |
|---|---|---|---|
| Безопасность | Безопасна. Становится nil. |
Небезопасна. Приводит к крашу. | |
| Тип | Опциональный (T?). |
Неопциональный (T). |
|
| Использование | Когда объект может быть освобожден. | Когда объект гарантированно живет дольше. |
Опасный пример:
class Processor {
unowned let formatter: Formatter // Рискованно!
init(formatter: Formatter) { self.formatter = formatter }
func process() {
print(formatter.name) // CRASH, если formatter удален.
}
}
Безопасная альтернатива с weak:
class Processor {
weak var formatter: Formatter? // Безопасно.
func process() {
guard let formatter = formatter else { return } // Грамотная проверка.
print(formatter.name)
}
}
Правило: Используйте unowned только при строгой гарантии жизненного цикла, например, когда self владеет объектом, который хранит unowned ссылку на этот же self (классический пример — [unowned self] в замыкании, время жизни которого точно короче). В сомнительных случаях всегда выбирайте weak.
Ответ 18+ 🔞
А, ну это же про наши любимые ссылочки в свифте, да? Слушай, тут такая история, блядь. Вот есть у тебя unowned — это как взять в долг у соседа дрель, а потом этот сосед, сука, съебался в другой город, а ты пытаешься её включить. И тебе не просто «ой, дрели нет», а тебе вся система в пизду летит, EXC_BAD_ACCESS, краш, синий экран в душе, пиздец полный. Это ссылка, которая ни хуя не следит, жив ли объект, на который она указывает. Умер он — и ты, дурак, тянешься к трупу, а там уже разложение.
А weak — это поумнее. Это как та же дрель, но у тебя есть бумажка: «Если Вася съебался, дрель испарится». То есть ссылка сама станет nil, и ты, прежде чем сверлить, проверяешь: «А Вася-то на месте? А, нет. Ну и хуй с ним». Безопасно, спокойно, неловко, но не смертельно.
Короче, смотри табличку, чтобы не ебать мозг:
| Критерий | weak |
unowned |
|---|---|---|
| Безопасность | Почти как презерватив. Станет nil. |
Русская рулетка. Краш нахуй. |
| Тип | Опциональный (T?). «Может, есть, а может, и нет». |
Неопциональный (T). «Есть, блядь, и всё тут!» (а на деле уже нет). |
| Когда юзать | Когда объект может приказать долго жить раньше тебя. | Только когда ты на 150% уверен, что объект переживёт тебя. |
Вот смотри, как можно наебнуться с unowned:
class Processor {
unowned let formatter: Formatter // О, какой смелый!
init(formatter: Formatter) { self.formatter = formatter }
func process() {
print(formatter.name) // ПИЗДЕЦ, если formatter уже в мусорке.
}
}
Представь: formatter удалили, а этот Processor как дурак тыкается в освобождённую память. И всё, приехали, игра окончена, ебать твои костыли.
А вот как сделать по-человечески, с weak:
class Processor {
weak var formatter: Formatter? // Умно, осторожно.
func process() {
guard let formatter = formatter else { return } // Проверил — и спокоен, как удав.
print(formatter.name)
}
}
Итог, блядь: unowned — это для особых случаев, когда ты как в том анекдоте: «Я знаю, что делаю». Например, в замыкании [unowned self], когда само замыкание живёт меньше, чем self. А во всех остальных, даже чуть-чуть сомнительных, ситуациях — weak, и спать спокойно. Не геройствуй, а то потом дебажить будешь, волнение ебать, терпения ноль ебать.