ios - portugues - the swift programming language pdf



O que exatamente é o codificador init aDecoder? (2)

O requisito para implementar esse inicializador é uma consequência de duas coisas:

  1. O princípio da substituição de Liskov . Se S é uma subclasse de T (por exemplo, MyViewController é uma subclasse de ViewController ), então objetos S (instâncias de MyViewController ) devem poder ser substituídos em onde os objetos T (instâncias de ViewController ) são esperados.

  2. Os inicializadores não são herdados no Swift se algum inicializador for explicitamente definido na subclasse. Se um inicializador for fornecido explicitamente, todos os outros devem ser fornecidos explicitamente (o que pode ser chamado de super.init(...) ). Veja esta pergunta para a lógica. Está em Java, mas ainda se aplica.

No ponto 1, tudo o que o ViewController original pode fazer, a subclasse MyViewController deve ser capaz de fazer. Uma coisa é poder inicializar a partir de um determinado NSCoder . No ponto 2, sua subclasse MyViewController não herda automaticamente essa habilidade. Assim, você deve fornecer manualmente o inicializador que atende a esse requisito. Neste caso, você só precisa delegar para a superclasse, para que ela faça o que normalmente faria.

Estou aprendendo o desenvolvimento do iOS a partir de um curso on-line e toda vez que faço uma exibição personalizada (célula de exibição de tabela personalizada, célula de exibição de coleção, etc), o instrutor sempre implementa esse inicializador:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Por que exatamente eu sempre tenho que chamar isso? O que isso faz? Posso colocar propriedades dentro do init?


Answer #1

Vou começar esta resposta da direção oposta: e se você quiser salvar o estado de sua visão para o disco? Isso é conhecido como serialização . O reverso é a desserialização - restaurando o estado do objeto do disco.

O protocolo NSCoding define dois métodos para serializar e desserializar objetos:

encodeWithCoder(_ aCoder: NSCoder) {
    // Serialize your object here
}

init(coder aDecoder: NSCoder) {
    // Deserialize your object here
}

Então, por que é necessário na sua classe personalizada? A resposta é o Interface Builder. Quando você arrasta um objeto para um storyboard e o configura, o Interface Builder serializa o estado desse objeto para o disco e, em seguida, desserializa quando o storyboard é exibido na tela. Você precisa dizer ao Interface Builder como fazer isso. No mínimo, se você não adicionar nenhuma nova propriedade à sua subclasse, você pode simplesmente pedir à superclasse para fazer o empacotamento e desempacotamento para você, daí a super.init(coder: aDecoder) . Se sua subclasse é mais complexa, você precisa adicionar seu próprio código de serialização e desserialização para a subclasse.

Isso está em contraste com a abordagem do Visual Studio, que é gravar código em um arquivo oculto para criar o objeto em tempo de execução.





swift