В чем разница в Swift между "незанятыми (безопасными)" и "незаслуженными (небезопасными)"?
Apple Руководство по языку Swift Programming упоминает спецификаторы захвата unowned(safe)
и unowned(unsafe)
в дополнение к weak
и unowned
.
I (думаю, я) понимаю различия между weak
и unowned
; но в чем разница между unowned(safe)
и unowned(unsafe)
? Руководство не говорит.
Пожалуйста: не полагайтесь на простое выражение Objective-C.
Ответы
Ответ 1
Из того, что я понимаю, хотя я не могу найти окончательный источник от Apple, unowned
можно разбить на два варианта: safe
и unsafe
.
Голый unowned
- unowned(safe)
: это специально обернутая ссылка, которая генерирует исключение, если ссылается на освобожденный экземпляр.
Частный случай unowned(unsafe)
: это эквивалент Swift Objective C @property (assign)
или __unsafe_unretained
. Он не должен использоваться в программе Swift, потому что его целью является переход на код, написанный в Objective C.
Итак, вы увидите unowned(unsafe)
при просмотре обертки импорта для классов Cocoa, но не используйте ее, если вам это нужно, и вы узнаете, когда вам нужно.
Обновление
__unsafe_unretained
- простой указатель. Он не будет знать, когда указанный указатель был отменен, поэтому, когда он будет разыменован, основная память может быть мусором.
Если у вас есть дефект, в котором используется измененная переменная __unsafe_unretained
, вы увидите неустойчивое поведение. Иногда достаточно места для этой памяти достаточно хорошо, поэтому код будет работать, иногда он будет частично перезаписан, поэтому вы получите очень странные сбои, и иногда это место памяти будет содержать новый объект, поэтому вы получите нераспознанные исключения для селектора.
Переход к заметкам о выпуске ARC
__unsafe_unretained
указывает ссылку, которая не сохраняет объект, на который ссылается, и не установлена на нуль, если нет сильных ссылок на объект. Если объект, который он ссылается, освобождается, указатель остается висящим.
Ответ 2
Вот цитата из Форумы разработчиков Apple:
unowned
vs unowned(safe)
vs unowned(unsafe)
unowned(safe)
- это ссылка, не относящаяся к владельцам, которая утверждает, что объект все еще жив. Это похоже на слабую дополнительную ссылку который неявно разворачивается с помощью x!
каждый раз, когда он обращается к нему. unowned(unsafe)
похож на __unsafe_unretained
в ARC - это не владеющий ссылка, но нет времени проверки, что объект все еще жив на доступ, поэтому болтающиеся ссылки попадут в память мусора. unowned
всегда является синонимом unowned(safe)
в настоящее время, но что он будет оптимизирован до unowned(unsafe)
в -Ofast
строит, когда проверки времени выполнения отключены.
Ответ 3
Простое определение. что позволило бы устранить путаницу.
- несанкционированные атрибуты: если вы попытаетесь получить доступ к неопубликованной ссылке после того, как экземпляр, на который он ссылается, будет освобожден, ваша программа выйдет из строя.
- непризнанные (небезопасные) атрибуты: если вы попытаетесь получить доступ к небезопасной неопубликованной ссылке после того, как экземпляр, на который он ссылается, будет освобожден, ваша программа попытается получить доступ к ячейке памяти, в которой был экземпляр, который является небезопасным операция. (без гарантии, что это произойдет или произойдет сбой)
Ответ 4
Доступ к переменной можно получить, если она уже была деколирована с атрибутом:
бесхозный
- Программа знает, что она недействительна, и немедленно сбой.
- Определено поведение.
бесхозный (небезопасный)
- Программа ничего не знает.
- Он может немедленно сработать.
- Он может получить доступ к неизвестному адресу памяти и иметь странное состояние, пока оно не умрет в неожиданном месте.
- Поведение undefined. Жизнь усложняется.