Обе weak
и unowned
ссылки не создают strong
удержание на упомянутом объекте (иначе они не увеличивают количество сохранений, чтобы предотвратить освобождение ARC упомянутого объекта).
Но почему два ключевых слова? Это различие связано с тем, что Optional
типы встроены в язык Swift. Короткая история о них: необязательные типы обеспечивают безопасность памяти (это прекрасно работает с правилами конструктора Swift - которые являются строгими, чтобы обеспечить это преимущество).
weak
Ссылка допускает возможность его стать nil
(это происходит автоматически , когда объект ссылки освобождается), поэтому тип вашей собственности должен быть обязательно - так что вы, как программист, обязаны проверить его , прежде чем использовать его ( в основном компилятор заставляет вас, насколько это возможно, писать безопасный код).
An unowned
ссылка предполагает , что он никогда не станет в nil
течение его жизни. Во время инициализации должна быть установлена неизвестная ссылка - это означает, что ссылка будет определена как необязательный тип, который можно безопасно использовать без проверок. Если каким-либо образом объект, на который ссылаются, освобождается, то приложение будет аварийно завершать работу, когда будет использоваться неподдерживаемая ссылка.
Из документов Apple :
Используйте слабую ссылку всякий раз, когда это допустимо, чтобы эта ссылка стала нулевой в какой-то момент в течение своего срока службы. И наоборот, используйте неизвестную ссылку, если вы знаете, что ссылка никогда не будет равна нулю, если она была установлена во время инициализации.
В документации есть несколько примеров, в которых обсуждаются циклы сохранения и способы их разрыва. Все эти примеры взяты из документов .
Пример weak
ключевого слова:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
}
А теперь, для некоторого искусства ASCII (вы должны посмотреть документы - у них есть красивые диаграммы):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
В Person
и Apartment
примере показана ситуация , когда два свойства, оба из которых разрешено быть нулевыми, имеют потенциал , чтобы вызвать сильный опорный цикл. Этот сценарий лучше всего решить со слабой ссылкой. Обе сущности могут существовать без строгой зависимости друг от друга.
Пример unowned
ключевого слова:
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}
В этом примере a Customer
может иметь или не иметь a CreditCard
, но a CreditCard
всегда будет связано с a Customer
. Чтобы представить это, у Customer
класса есть необязательное card
свойство, но у CreditCard
класса есть необязательное (и не принадлежащее) customer
свойство.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
В Customer
и CreditCard
примере показана ситуация , когда одно свойство, которое разрешено быть нулем , а другое свойство , которое не может быть нулем имеет потенциал , чтобы вызвать сильный опорный цикл. Этот сценарий лучше всего разрешается с помощью неизвестной ссылки.
Примечание от Apple:
Слабые ссылки должны быть объявлены как переменные, чтобы указать, что их значение может изменяться во время выполнения. Слабая ссылка не может быть объявлена константой.
Существует также третий сценарий, когда оба свойства должны всегда иметь значение, и ни одно из свойств не должно быть равно нулю после завершения инициализации.
И есть также классические сценарии сохранения цикла, которых следует избегать при работе с замыканиями.
Для этого я советую вам посетить документацию Apple или прочитать книгу .