Свифт имеет:
- Сильные Ссылки
- Слабые ссылки
- Неизвестные ссылки
Чем неподходящая ссылка отличается от слабой ссылки?
Когда безопасно использовать ссылку без ссылки?
Являются ли неизвестные ссылки угрозой безопасности, такой как висячие указатели в C / C ++?
unowned
для классов, которые мы контролируем, для классов Apple,weak
потому что мы не можем точно гарантировать, что он делаетОтветы:
Обе
weak
иunowned
ссылки не создаютstrong
удержание на упомянутом объекте (иначе они не увеличивают количество сохранений, чтобы предотвратить освобождение ARC упомянутого объекта).Но почему два ключевых слова? Это различие связано с тем, что
Optional
типы встроены в язык Swift. Короткая история о них: необязательные типы обеспечивают безопасность памяти (это прекрасно работает с правилами конструктора Swift - которые являются строгими, чтобы обеспечить это преимущество).weak
Ссылка допускает возможность его статьnil
(это происходит автоматически , когда объект ссылки освобождается), поэтому тип вашей собственности должен быть обязательно - так что вы, как программист, обязаны проверить его , прежде чем использовать его ( в основном компилятор заставляет вас, насколько это возможно, писать безопасный код).An
unowned
ссылка предполагает , что он никогда не станет вnil
течение его жизни. Во время инициализации должна быть установлена неизвестная ссылка - это означает, что ссылка будет определена как необязательный тип, который можно безопасно использовать без проверок. Если каким-либо образом объект, на который ссылаются, освобождается, то приложение будет аварийно завершать работу, когда будет использоваться неподдерживаемая ссылка.Из документов Apple :
В документации есть несколько примеров, в которых обсуждаются циклы сохранения и способы их разрыва. Все эти примеры взяты из документов .
Пример
weak
ключевого слова:А теперь, для некоторого искусства ASCII (вы должны посмотреть документы - у них есть красивые диаграммы):
В
Person
иApartment
примере показана ситуация , когда два свойства, оба из которых разрешено быть нулевыми, имеют потенциал , чтобы вызвать сильный опорный цикл. Этот сценарий лучше всего решить со слабой ссылкой. Обе сущности могут существовать без строгой зависимости друг от друга.Пример
unowned
ключевого слова:В этом примере a
Customer
может иметь или не иметь aCreditCard
, но aCreditCard
всегда будет связано с aCustomer
. Чтобы представить это, уCustomer
класса есть необязательноеcard
свойство, но уCreditCard
класса есть необязательное (и не принадлежащее)customer
свойство.В
Customer
иCreditCard
примере показана ситуация , когда одно свойство, которое разрешено быть нулем , а другое свойство , которое не может быть нулем имеет потенциал , чтобы вызвать сильный опорный цикл. Этот сценарий лучше всего разрешается с помощью неизвестной ссылки.Примечание от Apple:
Существует также третий сценарий, когда оба свойства должны всегда иметь значение, и ни одно из свойств не должно быть равно нулю после завершения инициализации.
И есть также классические сценарии сохранения цикла, которых следует избегать при работе с замыканиями.
Для этого я советую вам посетить документацию Apple или прочитать книгу .
источник
weak var Person?
противvar Person?
?Q1. Чем «Неизвестная ссылка» отличается от «Слабой ссылки»?
Слабая ссылка:
Неизвестная ссылка:
Когда использовать каждый:
Q2. Когда безопасно использовать «ссылку без ссылки»?
Как указывалось выше, предполагается, что неподтвержденная ссылка всегда имеет значение. Таким образом, вы должны использовать его только тогда, когда вы уверены, что ссылка никогда не будет равна нулю. Документы Apple иллюстрируют вариант использования для неиспользованных ссылок в следующем примере.
Предположим, у нас есть два класса
Customer
иCreditCard
. Клиент может существовать без кредитной карты, но кредитная карта не будет существовать без клиента, то есть можно предположить, что у кредитной карты всегда будет клиент. Итак, они должны иметь следующие отношения:Q3. Являются ли «неизвестные ссылки» ссылками на угрозу безопасности, такие как «висячие указатели» в C / C ++
Я так не думаю.
Поскольку неизвестные ссылки являются просто слабыми ссылками, которые гарантированно имеют значение, это никоим образом не должно представлять угрозу безопасности. Однако, если вы попытаетесь получить доступ к неизвестной ссылке после того, как экземпляр, на который она ссылается, будет освобожден, вы вызовете ошибку времени выполнения, и приложение вылетит.
Это единственный риск, который я вижу с этим.
Ссылка на Apple Docs
источник
unowned
для свойства parent в дочернем классе. слабый наоборот. Хорошее объяснение @myxtic!unowned
ссылки - это простоweak
ссылки, которые гарантированно имеют значение!Если « я» может быть нулевым в замыкании, используйте « слабое я» .
Если self никогда не будет нулевым в закрытии, используйте [unowned self] .
Если происходит сбой, когда вы используете [unowned self], тогда self, вероятно, равно нулю в какой-то момент в этом закрытии, и вам, вероятно, нужно вместо этого использовать [слабое self] .
Посмотрите примеры использования сильных , слабых и неиспользуемых в замыканиях:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
источник
self
быть ноль?Выдержки из ссылки
Несколько заключительных пунктов
источник
И ссылки,
weak
иunowned
ссылки не влияют на количество ссылок объекта. Но слабая ссылка всегда будет необязательной, то есть она может быть нулевой, тогда какunowned
ссылки никогда не могут быть нулевыми, поэтому они никогда не будут необязательными. При использовании необязательной ссылки вы всегда должны учитывать вероятность того, что объект будет нулевым. В случае отсутствия ссылки, вы должны убедиться, что объект никогда не равен нулю. Использование неизвестной ссылки на нулевой объект будет аналогично принудительному развертыванию необязательного объекта nil.При этом безопасно использовать неизвестную ссылку, если вы уверены, что время жизни объекта больше, чем у ссылки. Если это не так, лучше использовать слабую ссылку.
Что касается третьей части вопроса, я не думаю, что ссылка без ссылки похожа на висячий указатель. Когда мы говорим о подсчете ссылок, мы обычно ссылаемся на строгий подсчет ссылок объекта. Точно так же swift поддерживает количество неизвестных и слабых ссылок для объекта (слабые ссылки указывают на то, что называется «боковой таблицей», а не на сам объект). Когда счетчик сильных ссылок достигает нуля, объект деинициализируется, но он не может быть освобожден, если счетчик неизвестных ссылок больше нуля.
Теперь висячий указатель - это то, что указывает на область памяти, которая уже была освобождена. Но в быстром, поскольку память может быть освобождена только до тех пор, пока существует неизвестная ссылка на объект, она не может вызвать висячий указатель.
Есть много статей, в которых более подробно обсуждается быстрое управление памятью. Вот один.
источник
Неизвестные ссылки - это своего рода слабая ссылка, используемая в случае отношения Same-Lifetime между двумя объектами, когда объект должен когда-либо принадлежать только одному другому объекту. Это способ создать неизменную связь между объектом и одним из его свойств.
В примере, приведенном в промежуточном быстром видео WWDC, человек владеет кредитной картой, и у кредитной карты может быть только один держатель. На кредитной карте человек не должен быть необязательным свойством, потому что вы не хотите, чтобы у кредитной карты был только один владелец. Вы можете разорвать этот цикл, сделав свойство владельца по кредиту слабой ссылкой, но для этого также необходимо, чтобы оно было необязательным и переменным (в отличие от константы). Неизвестная ссылка в этом случае означает, что, хотя у CreditCard нет собственного пакета в Лице, его жизнь зависит от него.
источник
Используйте,
unowned
когда вы уверены, чтоself
никогдаnil
не окажетесь в точке, к которой вы обращаетесьself
в этой точке.Пример (конечно, вы можете добавить цель напрямую
MyViewController
, но, опять же, это простой пример) .:Используйте,
weak
когда есть возможность,self
может бытьnil
в точке, к которой вы обращаетесьself
.Пример:
Минусы
unowned
:Минусы
weak
:Если вы не уверены, используйте
weak
. Подождите , я имею в виду, спросите здесь, на StackOverflow, что вы должны делать в вашем случае! Использование слабых все время, когда вы не должны, просто сбивает с толку вас и читателя вашего кода.источник