Управление памятью в Swift: Зачем нужен optional unowned?
👋 Управление памятью имеет критическое значение для предотвращения утечек и обеспечения стабильной работы приложений.
В языке Swift для этого реализованы два замечательных механизма — weak и unowned. Но существует еще третий механизм, о котором стоит поговорить, — это optional unowned.
Давайте разберемся, для чего он нужен и действительно ли он необходим.
Что говорит документация?
Документация Swift утверждает:
You can mark an optional reference to a class as unowned. In terms of the ARC ownership model, an unowned optional reference and a weak reference can both be used in the same contexts. The difference is that when you use an unowned optional reference, you’re responsible for making sure it always refers to a valid object or is set to nil.
Вы можете пометить опциональную ссылку на класс как unowned. С точки зрения модели владения ARC, unowned optional ссылка и слабая ссылка могут использоваться в одних и тех же контекстах. Разница заключается в том, что при использовании unowned optional ссылки вы берете на себя ответственность за то, чтобы она всегда ссылалась на действительный объект или была равна nil.
Таким образом, можно использовать unowned optional, но это лишь синтаксическая особенность языка Swift. Мы можем добавить знак ? к любому типу, и он станет опциональным.
Разница между unowned и optional unowned
Важно понимать, что unowned подразумевает, что значение будет существовать во время обращения к нему; иначе произойдет крах приложения.
В то же время optional unowned позволяет значению быть nil, но при обращении оно должно быть не nil; в противном случае тоже произойдет крах.
Реальный кейс
В документации можно найти некоторые натянутые примеры использования optional unowned, но меня интересует, есть ли реальные кейсы, когда это оправдано. Пока что я склоняюсь к варианту, что реальных полезных сценариев использования такого механизма нет, и вот почему:
- Слабые ссылки (weak) были разработаны не случайно. Они явно предназначены для обработки случаев, когда значение может отсутствовать. В отличие от них, использование unowned подразумевает уверенность в наличии значения.
- Замечание из документации.
The underlying type of an optional value is Optional, which is an enumeration in the Swift standard library. However, optionals are an exception to the rule that value types can’t be marked with unowned.
The optional that wraps the class doesn’t use reference counting, so you don’t need to maintain a strong reference to the optional.
Базовым типом опционального значения является Optional, которое представляет собой перечисление в стандартной библиотеке Swift. Однако, опциональные значения являются исключением из правила, согласно которому типы значений не могут быть помечены как unowned.
Опциональное значение, которое обертывает класс, не использует подсчет ссылок, поэтому вам не нужно удерживать сильную ссылку на опциональное значение.
Изучив эти моменты, я прихожу к выводу, что механизм optional unowned не предоставляет значительных практических преимуществ для безопасного кода.
Его существование в Swift, скорее всего, связано с особенностями типизации и моделирования объектов, а не с реальной необходимостью.
✍️ Напишите в комментариях, что вы думаете об optional unowned. Если у вас есть реальные кейсы его использования, буду рад узнать о них!