Estou desenvolvendo exclusivamente para o iOS 5 usando o ARC. Should IBOutlet
s para UIView
s (e subclasses) ser strong
ou weak
?
Os seguintes:
@property (nonatomic, weak) IBOutlet UIButton *button;
Se livraria de tudo isso:
- (void)viewDidUnload
{
// ...
self.button = nil;
// ...
}
Existem problemas para fazer isso? Os modelos estão usando strong
as propriedades geradas automaticamente, criadas ao se conectar diretamente ao cabeçalho no editor 'Interface Builder', mas por quê? O UIViewController
já possui uma strong
referência ao view
que retém suas subvisões.
IBOutletCollection()
não deve serweak
, caso contrário, ele retornará comonil
.strong
Respostas:
A corrente recomendado melhores práticas da Apple é para IBOutlets a ser forte , a menos fraco é especificamente necessário para evitar a reter ciclo. Como Johannes mencionou acima, isso foi comentado na sessão "Implementando projetos de interface do usuário no Interface Builder" da WWDC 2015, onde um engenheiro da Apple disse:
Perguntei sobre isso no Twitter a um engenheiro da equipe de IB e ele confirmou que forte deve ser o padrão e que os documentos do desenvolvedor estão sendo atualizados.
https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104
fonte
AVISO, RESPOSTA ATUALIZADA : esta resposta não está atualizada conforme WWDC 2015, para obter a resposta correta, consulte a resposta aceita (Daniel Hall) acima. Esta resposta ficará registrada.
Resumido da biblioteca do desenvolvedor :
fonte
Embora a documentação recomende o uso
weak
de propriedades para sub-visualizações, desde o iOS 6 parece bom usá-lostrong
(o qualificador de propriedade padrão). Isso é causado pela mudança emUIViewController
que as visualizações não são mais descarregadas.Dito isto, estou dividido entre usar
e
no iOS 6 e posterior:
O uso
weak
indica claramente que o controlador não deseja a propriedade do botão.Mas omitir
weak
não faz mal no iOS 6 sem descarregar a visualização e é mais curto. Alguns podem apontar que também é mais rápido, mas ainda não encontrei um aplicativo muito lento por causa deweak
IBOutlet
s.Não usar
weak
pode ser percebido como um erro.Conclusão: desde o iOS 6, não podemos mais entender errado desde que não utilizemos o descarregamento de visualizações. Hora de festejar. ;)
fonte
nil
manualmente.weak
é um pouco mais barato no ARM64: Dweak
propriedades ou__weak
variáveis de instância são o caminho a percorrer. Eu só queria ressaltar que há menos potencial de erro aqui. Quanto aweak
ser mais barato no arm64, eu nem vi um problema de desempenho na vida real comweak
IBOutlet
s no armv7. :)strong
faz sentido também.strong
só é prejudicial se você usar o descarregamento de visualizações - mas quem usa atualmente? :)Não vejo nenhum problema com isso. Antes do ARC, eu sempre fiz meus IBOutlets
assign
, pois eles já são mantidos por suas superviews. Se você as criarweak
, não precisará defini-las em viewDidUnload, como você indica.Uma ressalva: você pode oferecer suporte ao iOS 4.x em um projeto ARC, mas se o fizer, não poderá usá-
weak
lo; portanto, será necessário fazê-loassign
; nesse caso, você ainda deseja anular a referênciaviewDidUnload
para evitar um ponteiro pendente. Aqui está um exemplo de um bug de ponteiro danificado que eu experimentei:Um UIViewController possui um UITextField para CEP. Ele usa CLLocationManager para inverter o código geográfico da localização do usuário e definir o CEP. Aqui está o retorno de chamada do delegado:
Descobri que se eu rejeitasse essa visualização no momento certo e não fizesse o self.zip
viewDidUnload
, o retorno de chamada delegado poderia gerar uma exceção de acesso ruim no self.zip.text.fonte
weak
propriedades não precisam ser detalhadasviewDidUnload
. Mas por que o modelo da Apple para criação de pontos de venda inclui um[self setMySubview:nil]
?IBOutlet
deve ser forte, por razões de desempenho. Consulte Referência do Storyboard, IBOutlet forte, Base de cena no iOS 9A partir do Xcode 7, sugere
strong
Se você assistir a sessão 407 da WWDC 2015 Implementando designs de interface do usuário no Interface Builder , sugere (transcrição de http://asciiwwdc.com/2015/sessions/407 )
fonte
No desenvolvimento iOS, o carregamento do NIB é um pouco diferente do desenvolvimento do Mac.
No desenvolvimento para Mac, um IBOutlet geralmente é uma referência fraca: se você tiver uma subclasse do NSViewController, apenas a visualização de nível superior será mantida e quando você desalocar o controlador, todas as subvisões e saídas serão liberadas automaticamente.
O UiViewController usa a codificação de valores-chave para definir as saídas usando referências fortes. Portanto, quando você desalocar seu UIViewController, a vista superior será desalocada automaticamente, mas você também deve desalocar todas as suas saídas no método desalocação.
Nesta postagem do Big Nerd Ranch , eles abordam este tópico e também explicam por que o uso de uma referência forte no IBOutlet não é uma boa opção (mesmo se recomendado pela Apple neste caso).
fonte
Uma coisa que gostaria de salientar aqui, e isso é, apesar do que os engenheiros da Apple declararam em seu próprio vídeo da WWDC 2015 aqui:
https://developer.apple.com/videos/play/wwdc2015/407/
A Apple continua mudando de idéia sobre o assunto, o que nos diz que não existe uma resposta certa para essa pergunta. Para mostrar que até os engenheiros da Apple estão divididos sobre esse assunto, dê uma olhada no código de exemplo mais recente da Apple e você verá que algumas pessoas usam pouco e outras não.
Este exemplo do Apple Pay usa fraco: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID
Como este exemplo imagem a imagem: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_Plift_Player_Player_Player_Player_Player_Player
Assim como o exemplo Lister: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57
Assim como o exemplo do Local Principal: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElement
Como o exemplo de visualização do controlador de exibição: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_Details
Da mesma forma que o exemplo do HomeKit: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Homes_ID23
Todos esses são totalmente atualizados para o iOS 9 e todos usam pontos fracos. A partir disso, aprendemos que A. A questão não é tão simples como algumas pessoas pensam ser. B. A Apple mudou de idéia repetidamente, e C. Você pode usar o que quer que te faça feliz :)
Agradecimentos especiais a Paul Hudson (autor de www.hackingwithsift.com), que me deu os esclarecimentos e as referências para esta resposta.
Espero que isso esclareça um pouco melhor o assunto!
Cuidar.
fonte
Na WWDC 2015, há uma sessão sobre Implementando designs de interface do usuário no Interface Builder . Em torno da marca de 32 minutos, ele diz que você sempre quer se
@IBOutlet
fortalecer .fonte
Esteja ciente,
IBOutletCollection
deveria ser@property (strong, nonatomic)
.fonte
copy
como é umNSArray
?Parece que algo mudou ao longo dos anos e agora a Apple recomenda usar forte em geral. A evidência em sua sessão do WWDC está na sessão 407 - Implementando designs de interface do usuário no Interface Builder e começa às 32:30. Minha nota do que ele diz é (quase, se não exatamente, citando-o):
as conexões de tomada em geral devem ser fortes, especialmente se conectarmos uma subvisão ou restrição que nem sempre é mantida pela hierarquia da visualização
pode ser necessária uma conexão de saída fraca ao criar visualizações personalizadas que tenham alguma referência a algo de backup na hierarquia de visualizações e, em geral, não é recomendado
Em outras alas, deve ser sempre forte agora, desde que algumas de nossas visualizações personalizadas não criem um ciclo de retenção com algumas das visualizações na hierarquia de visualizações
EDIT:
Alguns podem fazer a pergunta. Mantê-lo com uma referência forte não cria um ciclo de retenção como o controlador de visualização raiz e a visualização proprietária mantém a referência a ele? Ou por que isso mudou aconteceu? Eu acho que a resposta está no início desta conversa, quando eles descrevem como as pontas são criadas a partir da xib. Existe uma ponta separada criada para um VC e para a exibição. Eu acho que essa pode ser a razão pela qual eles mudam as recomendações. Ainda assim, seria bom obter uma explicação mais profunda da Apple.
fonte
Eu acho que a informação mais importante é: Os elementos no xib são automaticamente em sub-visões de exibição. Subviews é NSArray. O NSArray possui seus elementos. etc têm fortes indicadores sobre eles. Portanto, na maioria dos casos, você não deseja criar outro ponteiro forte (IBOutlet)
E com o ARC, você não precisa fazer nada
viewDidUnload
fonte