Swift tem:
- Referências Fortes
- Referências fracas
- Referências não proprietárias
Qual é a diferença entre uma referência não proprietária e uma referência fraca?
Quando é seguro usar uma referência não proprietária?
As referências não proprietárias são um risco de segurança, como ponteiros pendentes em C / C ++?
unowned
para as classes que controlam, para as classes da Apple, o usoweak
, porque não podemos garantir ao certo o que ele fazRespostas:
As referências
weak
eunowned
não criam umastrong
retenção no objeto referido (também conhecido como não aumentam a contagem de retenção para impedir que o ARC desaloque o objeto referido).Mas por que duas palavras-chave? Essa distinção tem a ver com o fato de os
Optional
tipos serem integrados na linguagem Swift. Para encurtar a história: tipos opcionais oferecem segurança à memória (isso funciona muito bem com as regras de construtor de Swift - que são rígidas para fornecer esse benefício).Uma
weak
referência permite a possibilidade de se tornarnil
(isso acontece automaticamente quando o objeto referenciado é desalocado); portanto, o tipo de sua propriedade deve ser opcional - para que você, como programador, seja obrigado a verificá-la antes de usá-lo (basicamente o O compilador obriga você, na medida do possível, a escrever um código seguro).Uma
unowned
referência presume que nunca se tornaránil
durante sua vida útil. Uma referência não proprietária deve ser definida durante a inicialização - isso significa que a referência será definida como um tipo não opcional que pode ser usado com segurança sem verificações. Se, de alguma forma, o objeto que está sendo referido for desalocado, o aplicativo falhará quando a referência não proprietária for usada.Dos documentos da Apple :
Nos documentos, existem alguns exemplos que discutem ciclos de retenção e como quebrá-los. Todos esses exemplos são extraídos dos documentos .
Exemplo da
weak
palavra-chave:E agora, para algumas obras de arte ASCII (você deve consultar os documentos - eles têm belos diagramas):
O exemplo
Person
eApartment
mostra uma situação em que duas propriedades, que são permitidas nulas, têm o potencial de causar um forte ciclo de referência. Este cenário é melhor resolvido com uma referência fraca. Ambas as entidades podem existir sem ter uma dependência estrita da outra.Exemplo da
unowned
palavra-chave:Neste exemplo, a
Customer
pode ou não ter aCreditCard
, mas aCreditCard
sempre será associado a aCustomer
. Para representar isso, aCustomer
classe possui umacard
propriedade opcional , mas aCreditCard
classe possui uma propriedade não opcional (e não proprietária)customer
.O exemplo
Customer
eCreditCard
mostra uma situação em que uma propriedade que pode ser nula e outra que não pode ser nula têm o potencial de causar um forte ciclo de referência. Este cenário é melhor resolvido com uma referência não proprietária.Nota da Apple:
Há também um terceiro cenário em que ambas as propriedades devem sempre ter um valor e nenhuma deve ser nula depois que a inicialização estiver concluída.
E também há os cenários clássicos de ciclo de retenção a serem evitados ao trabalhar com fechamentos.
Para isso, recomendo que você visite os documentos da Apple ou leia o livro .
fonte
weak var Person?
vs.var Person?
?Q1 Qual é a diferença entre uma “referência não proprietária” e uma “referência fraca”?
Referência fraca:
Referência não proprietária:
Quando usar cada um:
Q2 Quando é seguro usar uma "referência não proprietária"?
Como citado acima, presume-se que uma referência não proprietária sempre tenha um valor. Portanto, você deve usá-lo apenas quando tiver certeza de que a referência nunca será nula. O Apple Docs ilustra um caso de uso para referências não proprietárias através do exemplo a seguir.
Suponha que temos duas classes
Customer
eCreditCard
. Um cliente pode existir sem cartão de crédito, mas um cartão de crédito não existirá sem um cliente, ou seja, pode-se supor que um cartão de crédito sempre terá um cliente. Portanto, eles devem ter o seguinte relacionamento:Q3 A referência não proprietária faz referência a um risco de segurança como "ponteiros pendentes" em C / C ++
Acho que não.
Como as referências não proprietárias são apenas referências fracas que garantem um valor, não deve ser um risco à segurança. No entanto, se você tentar acessar uma referência não proprietária após a desalocação da instância que ela referencia, você acionará um erro de tempo de execução e o aplicativo falhará.
Esse é o único risco que vejo com isso.
Link para o Apple Docs
fonte
unowned
para a propriedade de pai na classe filho. fraco é vice-versa. Boa explicação @myxtic!unowned
referências são apenasweak
referências que garantem um valor!Se o eu puder ser nulo no fechamento, use [eu fraco] .
Se o eu nunca for nulo no fechamento, use [eu sem dono] .
Se está travando quando você usa [self sem dono] , o self provavelmente é nulo em algum momento desse fechamento e você provavelmente precisa usar [self fraco] .
Confira os exemplos de uso de fortes , fracos e sem dono em fechamentos:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
fonte
self
ser nulo?Extrações do link
Poucos pontos finais
fonte
Ambos
weak
eunowned
referências não terá impacto sobre a contagem de referência do objeto. Porém, referências fracas sempre serão opcionais, ou seja, podem ser nulas, enquantounowned
referências nunca podem ser nulas, portanto nunca serão opcionais. Ao usar uma referência opcional, você sempre terá que lidar com a possibilidade de o objeto ser nulo. No caso de uma referência não proprietária, você deverá garantir que o objeto nunca seja nulo. Usar uma referência não proprietária para um objeto nulo será semelhante a desembrulhar com força um opcional que seja nulo.Dito isto, é seguro usar uma referência não proprietária, onde você tem certeza de que o tempo de vida do objeto é maior que o da referência. Se não for esse o caso, é melhor usar uma referência fraca.
Quanto à terceira parte da pergunta, não acho que referências sem dono sejam semelhantes a um ponteiro pendente. Quando falamos sobre contagem de referência, geralmente nos referimos à contagem de referência forte do objeto. Da mesma forma, o swift mantém a contagem de referência não proprietária e a contagem de referência fraca para o objeto (pontos de referência fracos para algo chamado "tabela lateral" em vez do próprio objeto). Quando a contagem de referência forte chega a zero, o objeto é desinicializado, mas não pode ser desalocado se a contagem de referência não proprietária for maior que zero.
Agora, um ponteiro pendente é algo que aponta para um local de memória que já foi desalocado. Mas rapidamente, uma vez que a memória só pode ser desalocada enquanto houver uma referência não proprietária ao objeto, ela não pode causar um ponteiro pendente.
Existem muitos artigos que discutem o gerenciamento rápido de memória em mais detalhes. Aqui está um.
fonte
Referências não proprietárias são um tipo de referência fraca usada no caso de um relacionamento Same-Lifetime entre dois objetos, quando um objeto só deve pertencer a outro objeto. É uma maneira de criar uma ligação imutável entre um objeto e uma de suas propriedades.
No exemplo dado no vídeo WWDC rápido intermediário, uma pessoa possui um cartão de crédito, e um cartão de crédito pode ter apenas um titular. No cartão de crédito, a pessoa não deve ser uma propriedade opcional, porque você não deseja ter um cartão de crédito flutuando com apenas um proprietário. Você pode interromper esse ciclo tornando a propriedade do titular no crédito uma referência fraca, mas isso também exige que você a torne opcional e variável (e não constante). A referência não proprietária nesse caso significa que, embora o CreditCard não possua uma participação acionária em uma Pessoa, sua vida depende disso.
fonte
Use
unowned
quando tiver certeza deself
que nunca poderá estarnil
no ponto em que acessaself
nesse momento.Exemplo (é claro que você pode adicionar o destino diretamente de
MyViewController
, mas, novamente, é um exemplo simples):Use
weak
quando houver a possibilidade deself
estarnil
no ponto que você está acessandoself
.Exemplo:
Contras de
unowned
:Contras de
weak
:Se você não tiver certeza, use
weak
. Espere , quero dizer, pergunte aqui no StackOverflow o que você deve fazer no seu caso! Usar fraco o tempo todo quando você não deveria é apenas confuso para você e para o leitor do seu código.fonte