Непризнанный или слабый Почему мы должны отдавать предпочтение бесхозным?

Как сказал Apple в "The Swift Programming Language", похоже, нам следует отдать предпочтение unowned чем weak когда возможно:

Если захваченная ссылка никогда не станет равной нулю, она должна всегда учитываться как не имеющая ссылки, а не как слабая ссылка.

Из раздела "Слабые и неизвестные ссылки" на этой странице

Я знал разницу между этими двумя. Но мне любопытно, есть ли веская причина для предпочтения unowned чем weak? я думаю weak гораздо безопаснее, и мы всегда можем написать [weak obj] и необязательная проверка привязки, не задумываясь о возможности существования obj,

Это связано с соображениями производительности или с чем-то, что я пропустил? Или это полностью нормально использовать weak вместо unowned все время?

1 ответ

Решение

Слабые ссылки автоматически устанавливаются на 'nil' как только объект, на который они указывают, освобождается. Чтобы это было возможно в Swift, они должны быть объявлены как 'var' и необязательно:

class SomeOtherClass {
    weak var weakProperty: SomeClass?
}

Это хорошо, если 'weakProperty' может стать 'nil' в то время как случай 'SomeOtherClass' еще жив, и мы хотим проверить это перед использованием (делегаты - один из таких примеров). Но что, если какая-то ссылка никогда не будет логически 'nil' а мы все еще хотим предотвратить сохранение цикла? В Objective-C любая ссылка на объект может быть 'nil' (и обмен сообщениями 'nil' всегда молча терпит неудачу) поэтому дилеммы нет, мы всегда используем 'weak', Но у Свифта нет ниловых ссылок вообще. Мы используем опционы для чего-то, что может семантически не иметь ценности. Но мы не должны быть вынуждены использовать опционы для чего-то, что всегда должно иметь значение, просто чтобы иметь возможность разорвать цикл сохранения. Такая практика идет вразрез с предполагаемой семантикой необязательных. Это где 'unowned' приходит. Он поставляется в двух вариантах - 'unowned(safe)' а также 'unowned(unsafe)". Последнее опасно и эквивалентно 'assign' а также 'unsafe_unretained' из Objective-C. Но первый, который является стандартным (по крайней мере, во время отладки, не уверенный, оптимизируют ли они его как "unowned(небезопасный)" в сборках релизов), надежно завершит работу нашего приложения, если указанный объект будет преждевременно освобожден. Конечно, наше приложение будет аварийно завершать работу, если что-то пойдет не так, но отладку гораздо проще, чем молчаливо. Он должен молча терпеть неудачу только тогда, когда мы действительно этого хотим (в этом случае мы будем использовать 'weak')

ARC - Automatic Reference Counting это механизм, который управляет памятью, который применим для referenceвведите [О программе]. Объект освобождается только тогда, когда на нем 0 ссылок.

Strong reference - установлен по умолчанию, и этот тип безопасно использовать в линейных отношениях (нет цикла)

Retain cycle - это ситуация, когда каждый объект имеет сильные ссылки друг на друга

Сломать Retain cycle: weak а также unowned. Оба они не увеличивают счетчик удержания объекта на+1, и есть следующие отличия

Weak reference - Когда объект ссылки освобождается (nil), ARC установить weak ссылка на nilтоже. Поэтомуweak ссылка - это переменная var(не может быть постоянным let) [var vs let], поэтому этоoptional

weak var delegate: <Type>?

Общее

unowned - Когда объект ссылки освобождается (nil), unowned не становитсяnil потому как ARCне устанавливает его. Поэтомуunownedссылка не является обязательной

без владельца(по умолчанию)

safe unowned - использует runtime safety check выбросить исключение, если unowned ссылка была освобождена.

Fatal error: Attempted to read an unowned reference but object 0x7fa5dad3f0f0 was already deallocated

бесхозный (небезопасный)

unowned(unsafe) действует UnsafePointer что может создать dangling pointer. __unsafe_unretained от Objective-C. Это своего рода прямой доступ к памяти, которыйARCне обрабатывает. Это может вызвать неожиданное поведение, а не просто сбой. У него лучшая производительность

EXC_BAD_ACCESS

[Образец закрытия]

Другие вопросы по тегам