No momento, estou me ensinando a programação para iOS, e um conceito que acho realmente difícil de entender é a delegação. O que é isso? Por que e como é usado? Qual é a vantagem? A redação técnica do livro que estou lendo dificulta a compreensão.
11
Respostas:
Para entender
delegates
, você precisa entenderprotocols
.A
protocol
é como um contrato de serviço. Quando um objeto (geralmente umaUIViewController
subclasse, mas nem sempre) assina esse contrato, está dizendo "Estou interessado em fornecer lógica para apoiar a mensagem que você me envia". Isso é semelhante ao deNSNotificationCenter
se inscrever para um nível de interesse, a diferença sendo um objeto que emprega delegação pode ter apenas umdelegate
por vez, onde vários objetos podem se inscrever para o mesmoNSNotification
.A Apple usa delegação generalizada. Mais e mais, porém, você está vendo a Apple migrar muitas APIs
blocks
, que são semelhantescallbacks
em outros idiomas.Dito isto, a delegação ajuda a manter o MVC, mesmo que eu argumentasse que a delegação é um padrão de design por si só. Ajuda a separar os modelos dos controladores. Como no exemplo de John Cartwright, a
UITableView
sabe como exibir linhas e seções. Ele sabe como reutilizarUITableViewCells
por motivos de desempenho. Ele conhece todas as outras coisas que aUIScrollView
conhece. Mas ele não sabe quais células exibir. Não sabe com o que preencher essas células. Ele não sabe quais células reutilizar para um dadoNSIndexPath
. De qualquer forma, esse deve ser o trabalho do controlador. A delegação permite que a visualização da tabela descarregue essa lógica de não visualização em um objeto que deve ter essa responsabilidade de qualquer maneira.Mais do que isso, você não fica preso em um delegado durante toda a vida útil de um objeto. Você poderia facilmente ter várias fontes de dados para um dado
UITableView
e trocá-las em tempo de execução, conforme necessário.Portanto, por um lado, a delegação é ótima para fornecer dados e responder a interações de um objeto. Você vai vê-lo em um monte de aulas de UIKit, como um
UITableView
,UIPickerView
,UICollectionView
, etc.Mas a delegação também é muito útil quando você deseja passar informações entre objetos. Você pode facilmente criar seus próprios protocolos e inscrever seus próprios objetos para segui-los. Além disso, os métodos de protocolo são
@required
por padrão, mas você pode especificar alguns métodos a serem@optional
. Isso pode oferecer uma boa flexibilidade, se você precisar. Digamos que você tenha um controlador de exibição pai e um controlador de exibição filho. Talvez você esteja usando a nova API de contenção para fazer isso. Normalmente, se você precisar passar informações do pai para o filho, faça isso com uma propriedade. Feito. Mas e se você precisar passar as informações da criança de volta para os pais? Talvez algo mude na criança e você precise notificar os pais. Claro, você poderia fazer algum KVO em determinados valores. Mas talvez você queira saber quando um botão é pressionado. Basta criar um novo protocolo no controlador de exibição filhoNo MyChildViewController, quando seu botão é pressionado, basta verificar se o delegado responde à mensagem do delegado (se necessário e o delegado não implementa o método, você trava. Você pode criar o método
@optional
se necessário) e enviar isto:Em seguida, defina o delegado do MyChildViewController como
self
e implemente- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
no seu controlador de exibição pai. ESTRONDO! Você tem informações passadas de um filho para o pai. O relacionamento entre os dois objetos nem precisa ser tão próximo quanto pai / filho. É um contrato de serviço, desde que o objeto que se inscreve retenha o fim da barganha implementando os métodos necessários, você estará de acordo!NOTA: Os delegados devem ter propriedades fracas / atribuir, caso contrário, você entrará em um ciclo de retenção onde nenhum objeto poderá ser desalocado.
Espero que isto ajude!
fonte
Delegados são objetos que implementam determinadas funções quando não faz sentido implementar essas funções no objeto normal. É uma forma de injeção de dependência.
Para um exemplo concreto, veja o protocolo UITableViewDelegate. Esses métodos não fazem sentido para uma exibição de tabela ser implementada diretamente, porque as ações para selecionar uma linha de exibição de tabela serão diferentes em cada aplicativo e talvez em cada exibição de tabela. O delegado possui um método
-tableView:didSelectRowAtIndexPath:
para que você possa criar um objeto que lide com a seleção de linhas sem subclassificar a exibição de tabela para cada ação separada que você deseja implementar.fonte