nunca perca um Post

você já se viu desejando que a Apple incluísse um inicializador extra para uma classe UIKit? As extensões Swift tornam mais fácil adicionar novos inicializadores aos tipos sem subclassagem. Minhas notas rápidas em Adicionar um novo inicializador de conveniência a uma classe UIKit usando uma extensão Swift.

designado ou conveniência?

primeiramente uma recapitulação sobre os dois tipos de inicialização:

um inicializador designado é o inicializador primário para uma classe. Ele deve inicializar completamente todas as propriedades introduzidas por sua classe antes de chamar um inicializador de superclass. Uma classe pode ter mais de um inicializador designado.

um inicializador de conveniência é um inicializador secundário que deve chamar um inicializador designado da mesma classe. É útil quando você quer fornecer valores padrão ou outra configuração personalizada. Uma classe não requer inicializadores de conveniência.

as três regras

com isso claro você precisa se lembrar de três regras para inicializadores designados e de conveniência para tipos de classe:

  • um inicializador designado deve chamar um inicializador designado a partir da superclasse imediata.
  • um inicializador de conveniência deve chamar outro inicializador da mesma classe.
  • um inicializador de conveniência deve, em última análise, chamar um inicializador designado.O que isso significa para nós? Em termos simples, não ligue para super a partir do seu inicializador de conveniência. Chame outro inicializador (conveniência ou designado) da mesma classe.

    a Practical Example

    Let’s give it a try with a practical example. Criar e configurar uma vista de imagem a partir de uma imagem no catálogo de ativos pronto para usar com a disposição automática precisa de várias linhas de código:

    // Create the imagelet heartImage = UIImage(named: "Heart")// Now create the image view using the imagelet heartImageView = UIImageView(image: heartImage)// Configure the view remembering to disable// the autoresizing mask if we are using// Auto LayoutheartImageView.translatesAutoresizingMaskIntoConstraints = false// Sometime we must also override the default content modeheartImageView.contentMode = .scaleAspectFit// Finally add to the view hierarchyview.addSubview(heartImageView)

    isto fica chato rapidamente e eu sempre acabar esquecendo-se de desativar a tradução da máscara de redimensionamento automático.

    Criando um inicializador de conveniência

    vamos criar um novo UIImageView inicializador de conveniência que executa a configuração para nós. O nosso inicializador terá o nome da imagem no catálogo de activos e no modo de conteúdo. Uma vez que nem sempre queremos definir o modo de conteúdo, vamos torná-lo padrão para a escala a preencher. Aqui está o código.:

    extension UIImageView { convenience init?(named name: String, contentMode: UIViewContentMode = .scaleToFill) { guard let image = UIImage(named: name) else { return nil } self.init(image: image) self.contentMode = contentMode translatesAutoresizingMaskIntoConstraints = false }}

    alguns pontos a notar:

    • se o parâmetro Nome da imagem for inválido o nosso inicializador irá falhar e deverá retornar nil. Você define um inicializador falível com um ponto de interrogação após a palavra-chave init (init?).
    • uma vez que temos um válido UIImage chamamos o inicializador designado de UIImageView para criar a vista de imagem.
    • só podemos definir propriedades no objeto UIImageView depois de termos chamado o inicializador designado.

    utilização por exemplo

    // Default contentModelet heart = UIImageView(named: "Heart")// Specifying a contentModelet star = UIImageView(named: "Star", contentMode: .scaleAspectFit)

    Note que o inicializador inválido significa que o tipo return é opcional (UIImageView?) por isso, precisamos desembrulhá-lo antes de adicioná-lo ao superview.

    acesso à propriedade antes de iniciar o Self

    uma nota final sobre quando você pode acessar self para modificar propriedades. Se tentarmos definir uma propriedade de UIImageView antes de termos chamado self.init(image: UIImage?) temos um erro:

    // Does not compileself.contentMode = contentModeself.init(image: image)// Use of 'self' in property access 'contentMode'// before self.init initializes self

    se se lembrar que um inicializador designado tem de inicializar por completo todas as propriedades da sua classe, poderá talvez ver porque é que isto não é permitido. Mesmo que o compilador nos permitisse fazê-lo, o inicializador designado sobreporia o nosso valor com o valor padrão.

    Leitura Adicional

    as secções sobre inicialização e extensões do Swift Programming Language guide têm muito mais detalhes:

    • inicialização
    • extensões

Deixe uma resposta

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