o conceito de controle de acesso nos permite restringir como tipos, funções e outras declarações podem ser acessadas por outro código. O Swift oferece cinco níveis diferentes de controle de acesso, e fazer pleno uso deles pode ser crucial para escrever programas que separem claramente as preocupações e uma estrutura robusta.

quando definimos qualquer novo tipo, propriedade ou função no Swift, ele terá o nível de acesso internal por padrão. Isso significa que ele ficará visível para todos os outros códigos que vivem dentro do mesmo módulo — como um aplicativo, uma extensão do sistema, uma estrutura ou um pacote Swift.

como exemplo, digamos que estamos construindo um aplicativo de compras e que definimos uma classe chamadaPriceCalculator que nos permite calcular o preço total de uma variedade de produtos:

como atualmente não estamos especificando nenhum nível de acesso explícito, nossa classe PriceCalculator (e seu método calculatePrice) estará acessível de qualquer lugar em nosso aplicativo. No entanto, se quisermos compartilhar nossa nova classe com outros módulos (podemos, por exemplo, implementá-la dentro de uma estrutura que compartilhamos entre nosso aplicativo principal e uma extensão ou um aplicativo Apple Watch complementar), precisaremos torná-la public para que seja visível nesses contextos externos:

no entanto, a mudança acima não é suficiente. Embora agora possamos encontrar nossa classe fora do módulo em que está definida, não podemos criar nenhuma instância dele — já que seu inicializador (implícito) é, como qualquer outro código, internal por padrão. Para corrigir isso, vamos definir um inicializador public, que deixaremos vazio, pois não há trabalho real a ser feito dentro dele:

public class PriceCalculator { public init() {} ...}

agora podemos encontrar, inicializar e chamar nosso PriceCalculator dentro e fora de seu módulo — fantástico. Mas agora digamos que também estamos procurando subclassificá-lo para modificá-lo ou adicionar novas funcionalidades a ele. Embora isso seja possível atualmente em seu próprio módulo, é novamente algo que é impedido fora dele.

para alterar isso, teremos que usar o nível de controle de acesso atualmente mais aberto do Swift, que é apropriadamente nomeado open:

open class PriceCalculator { ...}

com a mudança acima no lugar, agora podemos criar subclasses personalizadas de PriceCalculator em qualquer lugar-que podem ter novos inicializadores, novas propriedades e novos métodos. Veja como podemos usar isso para implementar um DiscountedPriceCalculator, que nos permite aplicar um dado discount a todos os cálculos de preços:

acima, estamos definindo um novo método de cálculo de preço, mas seria indiscutivelmente muito mais apropriado substituir e modificar o método calculatePrice existente que herdamos de nossa classe base. Dessa forma, não haveria confusão em torno de qual método chamar, e poderíamos manter nossas duas classes consistentes.

para poder fazer isso, novamente temos que marcar a declaração original — desta vez nossa Declaração de método calculatePrice – como open:

open class PriceCalculator { public init() {} open func calculatePrice(for products: ) -> Int { ... }}

com o acima no lugar, agora podemos substituir livremente calculatePrice, em vez de ter que criar um método separado:

Então isso é internal, public e open – que são usados para abrir gradualmente uma declaração para uso público e modificação. Mas é claro que também podemos ir para o outro lado e ocultar partes do nosso código de serem descobertas e usadas. A princípio, pode parecer questionável Qual é o valor ao fazer isso, mas pode realmente nos ajudar a tornar nossa API muito mais estreita e focada — o que, por sua vez, pode facilitar a compreensão, o teste e o uso.

Então vamos agora ir até o outro lado do espectro de nível de acesso e dar uma olhada no nível mais restritivo — private. Qualquer tipo, propriedade ou método marcado como private só será visível dentro de seu próprio tipo (que também inclui extensões nesse tipo definido no mesmo arquivo).

qualquer coisa que deva ser considerada um detalhe de implementação privada de um determinado tipo deve ser marcada como private. Por exemplo, a propriedade discount da nossa calculadora de preços de antes era realmente destinada apenas a ser usada dentro de sua própria classe-então vamos em frente e tornar essa propriedade privada:

class DiscountedPriceCalculator: PriceCalculator { private let discount: Int ...}

nossa implementação anterior continuará funcionando exatamente da mesma maneira que antes, uma vez que discount permanecerá totalmente visível em nossa classe DiscountedPriceCalculator. No entanto, se quiséssemos estender ligeiramente essa visibilidade para incluir também outros tipos definidos no mesmo arquivo, teríamos que usar

class DiscountedPriceCalculator: PriceCalculator { fileprivate let discount: Int ...}

Com a alteração acima no lugar, agora podemos acessar o nosso discount imóvel de código relacionado definidas no mesmo arquivo, como este de extensão em UIAlertController o que nos permite facilmente mostrar um preço descrição para uma variedade de produtos dentro de um alerta:

Quando ele vem para libertar funções, tipos e extensões, private e fileprivate agir exatamente o mesmo. Eles só são diferentes quando aplicados a declarações definidas dentro de um tipo.

então, para resumir, esses são os cinco níveis de controle de acesso que o Swift oferece atualmente:

  • private mantém uma propriedade ou função privada dentro de seu tipo de enclosing, incluindo quaisquer extensões desse tipo que são definidas dentro do mesmo arquivo. Quando aplicado a um tipo, função ou extensão de nível superior, ele atua da mesma maneira que fileprivate.
  • fileprivate torna uma declaração visível dentro de todo o arquivo em que está definido, ocultando-a de todos os outros códigos.
  • internal é o nível de acesso padrão e torna visível uma declaração dentro de todo o módulo em que está definido.
  • public revela uma função, tipo, extensão ou propriedade fora de seu módulo.
  • open permite que uma classe seja subclassificada e uma função ou propriedade seja substituída, fora de seu módulo.

em geral, muitas vezes é melhor começar com o nível de acesso mais restritivo que uma determinada declaração pode praticamente ter e, em seguida, abrir as coisas mais tarde, se necessário. Dessa forma, estamos limitando os caminhos para a interação entre nossos vários tipos e funções, o que pode parecer uma coisa ruim, mas muitas vezes é realmente essencial para construir sistemas sustentáveis e bem estruturados.

Obrigado pela leitura! 🚀

(observe que este artigo não entrou em modificadores de acesso específicos para mutações, como private(set). Esses serão abordados por outro artigo básico no futuro.)

Suporte Swift por Sundell, verificando este patrocinador:

Instabug: Resolva bugs, travamentos e outros problemas muito mais rapidamente usando os rastreamentos detalhados de pilha, logs de rede e eventos de interface do usuário que o Instabug anexa automaticamente a cada relatório de bug. Usado por mim e por milhares de equipes de desenvolvimento iOS em todo o mundo. Experimente gratuitamente e integre-o com apenas uma única linha de código.

Deixe uma resposta

O seu endereço de email não será publicado.