В чем разница между слабой ссылкой и непризнанной ссылкой?
Свифт:
- Ссылок
- Слабые Ссылки
- Неизвестные Ссылки
чем неназванная ссылка отличается от слабой ссылки?
когда безопасно использовать ссылку без имени?
являются ли неизвестные ссылки угрозой безопасности, например висячие указатели в C / C++?
6 ответов:
и
weakиunownedссылки не создатьstrongудерживайте на упомянутом объекте (a.k.a. они не увеличивают счет удержания, чтобы предотвратить дугу от освобождения упомянутого объекта).но почему два ключевых слова? Это различие связано с тем, что
Optionalтипы встроены в языке Swift. Длинная история коротко о них:дополнительные типы безопасность памяти предложения (это работает красиво с конструктор Swift правила - которые являются строгими, чтобы обеспечить это преимущество).A
weakссылка позволяет возможность его статьnil(это происходит автоматически при освобождении объекта ссылки), поэтому тип вашего свойства должен быть необязательным - поэтому вы, как программист, обязаны проверить его перед использованием (в основном компилятор заставляет вас, насколько это возможно, писать безопасный код).An
unownedссылка предполагает, что он никогда не будет станьnilво время его жизни. Во время инициализации должна быть задана неизвестная ссылка - это означает, что ссылка будет определена как необязательный тип, который можно безопасно использовать без проверок. Если каким-то образом объект, на который ссылаются, освобождается, то приложение аварийно завершит работу, когда будет использоваться неназванная ссылка.С Apple docs:
используйте слабую ссылку всякий раз, когда она действительна для этой ссылки, чтобы стать нуль у некоторых точку в его жизни. И наоборот, использование бесхозяйного ссылка, когда вы знаете, что ссылка никогда не будет равна нулю один раз был установлен во время инициализации.
в документах есть несколько примеров, которые обсуждают сохранение циклов и как их разбить. Все эти примеры извлечены из документы.
пример
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)===== ApartmentThe
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может или не может естьCreditCard, аCreditCardвсегда связано сCustomer. Чтобы представить это,Customerкласс имеет необязательныйcardсобственность, аCreditCardкласс имеет необязательный (и не принадлежащий)customerсобственность.Customer ===(strong)==> CreditCard Customer <==(unowned)== CreditCardThe
CustomerиCreditCardпример показывает ситуацию, когда одно свойство, которому разрешено быть нулевым, и другое свойство, которое не может быть нулевым, могут вызвать сильный ссылочный цикл. Этот сценарий является лучшим разрешен с помощью неизвестной ссылки.Примечание от Apple:
слабые ссылки должны быть объявлены как переменные, чтобы указать, что их значение может изменяться во время выполнения. Слабая ссылка не может быть объявлен как постоянный.
существует также третий сценарий, когда оба свойства всегда должны иметь значение, и ни одно свойство никогда не должно быть равно нулю после завершения инициализации.
и есть также классический сохранить сценарии цикла, чтобы избежать при работе с замыканиями.
для этого, я призываю вас, чтобы посетить Apple docs, или читать книги.
Q1. Чем "неизвестная ссылка "отличается от"слабой ссылки"?
Слабые Ссылки:
слабая ссылка-это ссылка, которая не держит сильное влияние на экземпляр, на который он ссылается, и поэтому не останавливает ARC от удаления указанный экземпляр. Потому что слабые ссылки могут иметь "нет значения", вы должны объявить каждую слабую ссылку как имеющую необязательный тип. (Apple Документы)
Unowned Reference:
как и слабые ссылки, непризнанная ссылка не сохраняет сильного удержания на экземпляр он ссылается. В отличие от слабой ссылки, однако предполагается, что неназванная ссылка всегда имеет значение. Поэтому, неназванная ссылка всегда определяется как необязательный тип. (Apple Docs)
когда использовать каждый:
используйте слабую ссылку всякий раз, когда это действительно для того, чтобы ссылка стала ноль в какой-то момент в течение его жизни. И наоборот, использование бесхозяйного ссылка, когда вы знаете, что ссылка никогда не будет равна нулю один раз был установлен во время инициализации. (Apple Docs)
Q2. Когда безопасно использовать "непризнанную ссылку"?
как указано выше, предполагается, что у неавторизованной ссылки всегда есть значение. Поэтому вы должны использовать его только тогда, когда вы уверены, что ссылка никогда не будет нулевой. Apple Docs иллюстрирует прецедент использования для неназванных ссылок в следующем примере.
Предположим, у нас есть два класса
CustomerиCreditCard. Клиент может существовать без кредитной карты, но кредитная карта не будет существовать без клиента, т. е. можно предположить, что кредитная карта всегда будет иметь клиента. Таким образом, они должны иметь следующие отношения:class Customer { var card: CreditCard? } class CreditCard { unowned let customer: Customer }
Q3. Являются "бесхозяйными ссылка" ссылку на безопасности риск, как "висячие указатели" в C/с++
Я так не думаю.
поскольку непризнанные ссылки-это просто слабые ссылки, которые гарантированно имеют значение, это не должно быть угрозой безопасности в любом случае. Однако если вы попытаетесь получить доступ к неназванной ссылке после того, как экземпляр, на который она ссылается, будет освобожден, вы вызовете ошибку времени выполнения, и приложение аварийно завершит работу.
Это единственный риск, который я вижу с ним.
Если self может быть ноль в использовании закрытия [слабое самосознание].
Если self никогда не будет ноль в использовании закрытия [unowned self].
Если это сбой при использовании [unowned self] тогда self, вероятно, равен нулю в какой-то момент в этом закрытии, и вам, вероятно, нужно использовать [слабое самосознание] вместо.
Проверьте примеры использования сильный, слабый и unowned в затворы:
выписки из ссылке
несколько заключительных пунктов
- чтобы определить, если вам даже нужно беспокоиться о сильных, слабых, или unowned, спросите:"я имею дело с ссылочными типами". Если вы работаете с помощью структур или перечислений ARC не управляет памятью для этих типов и вам даже не нужно беспокоиться о том, чтобы указать слабый или непризнанный для эти константы или переменные.
- сильные ссылки хороши в иерархических отношениях, где родитель ссылается на ребенка, но не наоборот. На самом деле, сильные ссылки являются наиболее подходящим видом ссылки большую часть времени.
- если два экземпляра необязательно связаны друг с другом, убедитесь, что что один из этих примеров содержит слабую ссылку на другой.
- когда два экземпляра связаны таким образом, что один из экземпляры не могут существовать без другого, экземпляр с обязательная зависимость должна содержать неназванную ссылку на другой пример.
из книги Джона Хоффмана " освоение Swift 4.":
разница между слабой ссылкой и неназванной ссылкой заключается в том, что экземпляр, на который ссылается слабая ссылка, может быть равен нулю, тогда как экземпляр, на который ссылается неназванная ссылка, не может быть равен нулю. Это означает, что при использовании слабой ссылки свойство должно быть необязательным, так как оно может быть равно нулю.
Unowned references-это своего рода слабая ссылка, используемая в случае отношения одного и того же времени жизни между двумя объектами, когда объект должен принадлежать только одному другому объекту. Это способ создать неизменяемую привязку между объектом и одним из его свойств.
в примере, приведенном в промежуточном видео swift WWDC, человек владеет кредитной картой, и кредитная карта может иметь только одного владельца. На кредитной карте человека не должно быть дополнительного имущества, потому что вы не хотите, чтобы кредитная карта плавала только с одним владельцем. Вы можете разорвать этот цикл, сделав свойство держателя в кредите слабой ссылкой, но это также требует, чтобы вы сделали его необязательным, а также переменным (в отличие от константы). Непризнанная ссылка в этом случае означает, что, хотя кредитная карта не имеет доли владения в человеке, от нее зависит его жизнь.
class Person { var card: CreditCard? } class CreditCard { unowned let holder: Person init (holder: Person) { self.holder = holder } }
Comments