Que initializer (s) para substituir por UITableViewController subclasse
-
09-09-2019 - |
Pergunta
Eu tenho uma subclasse UITableViewController
que é instanciado, dependendo de onde ele é usado, em um NIB ou via código. Em ambos os casos eu quero fazer personalização no método de inicialização. Será que isso significa necessariamente que implementar ambos initWithNibName:bundle:
e initWithCoder:
, e que cada método chamar seu respectivo initializer super?
Enquanto eu não preciso disso agora, e se eu também quero ser capaz de criar uma instância do controlador de vista com initWithStyle:
? Será que eu, em seguida, precisa de 3 métodos de inicialização diferentes que reproduzem o mesmo comportamento?
Parece que isso viola o conjunto designado initializer convenção, como não seria essencialmente 3 initializers separados que não acabam chamando um método init comum. Ou há uma maneira de criar um comum designada initializer apoiando os 3 diferentes rotas instanciar?
Solução
A minha confusão foi baseada na crença equivocada de que cada classe deve ter um único inicializador designado. Isso não é verdade, e no caso de UITableViewController
há 3 inicializadores designados (tanto quanto eu posso dizer):
-
initWithStyle:
declarado localmente -
initWithNibName:bundle:
herdada deUIViewController
-
initWithCoder:
de adoptar protocoloNSCoding
Você precisa substituir 1 ou mais destes em sua subclasse dependendo de como sua subclasse é instanciado. No meu caso eu tive que implementar # 2 e # 3 já que a classe pode ser carregado a partir de um NIB, ou instanciado via código com referência a um NIB. (Imagino que é raro que você vai usar tanto initWithStyle:
e initWithNibName:bundle:
para uma única classe.)
Eu encontrei da Apple Codificação Diretrizes para Cocoa útil.
Outras dicas
Internamente,
-
-initWithStyle:
de UITableViewController chama-init
do Super seguida, defina o ivar_tableViewStyle
. -
-init
de UIViewController simplesmente chama-initWithNibName:bundle:
com argumentos padrão. - UITableViewController não override
-initWithNibName:bundle:
.
Portanto, se você substituir -initWithNibName:bundle:
então -initWithStyle:
vai adotar a mudança também. Claro que, para jogar pelo seguro (como você não deve confiar em detalhes de implementação), substituir os dois.
(E não há necessidade de -initWithCoder:
substituição a menos que você vai un / arquivar os casos.)
Para esclarecer, initWithStyle:
, sendo UITableViewController
está só publicou initializer nos docs, é seu único explícita inicializador designado.
initWithNibName:bundle:
é herdada de UIViewController e é o designado initializer para essa classe. Como tal, de acordo com as diretrizes de cacau, UITableViewController
deve substituir esse método (por implementá-lo). No entanto, isso não torná-lo um designado initializer de UITableViewController
.
initWithCoder:
é, como você aponta, um implícito designado initializer de NSCoding
.
Implementar:
- (void) viewDidLoad
e fazer a sua inicialização do componente lá.
Tem a vantagem de só fazer a inicialização quando a vista é realmente solicitado.
Ou apenas fazer um método de configuração separado invocado por todos os inicializadores.
Uma adição aos postos acima que -initWithCoder referência:
Se você adicionou acrescentou o controlador de vista a seu pai via construtor de interface (por exemplo: se o controlador de exibição está ligado a um controlador de barra de abas no construtor de interface)., Em seguida, você precisará substituir -initWithCoder
(-. InitWithNibName só será chamado quando você cria o controlador de vista de programação)