В чем основные риски использования `unowned` вместо `weak`?

Ответ

Ключевой риск 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, и спать спокойно. Не геройствуй, а то потом дебажить будешь, волнение ебать, терпения ноль ебать.