Estou trabalhando na captura de erros no meu aplicativo e estou pensando em usá-lo NSError
. Estou um pouco confuso sobre como usá-lo e como preenchê-lo.
Alguém poderia fornecer um exemplo de como eu preencho e uso NSError
?
Bem, o que eu costumo fazer é ter meus métodos que poderiam gerar erros no tempo de execução fazer referência a um NSError
ponteiro. Se algo realmente der errado nesse método, eu posso preencher a NSError
referência com dados de erro e retornar nulo do método.
Exemplo:
- (id) endWorldHunger:(id)largeAmountsOfMonies error:(NSError**)error {
// begin feeding the world's children...
// it's all going well until....
if (ohNoImOutOfMonies) {
// sad, we can't solve world hunger, but we can let people know what went wrong!
// init dictionary to be used to populate error object
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:@"ran out of money" forKey:NSLocalizedDescriptionKey];
// populate the error object with the details
*error = [NSError errorWithDomain:@"world" code:200 userInfo:details];
// we couldn't feed the world's children...return nil..sniffle...sniffle
return nil;
}
// wohoo! We fed the world's children. The world is now in lots of debt. But who cares?
return YES;
}
Podemos então usar o método como este. Nem se preocupe em inspecionar o objeto de erro, a menos que o método retorne zero:
// initialize NSError object
NSError* error = nil;
// try to feed the world
id yayOrNay = [self endWorldHunger:smallAmountsOfMonies error:&error];
if (!yayOrNay) {
// inspect error
NSLog(@"%@", [error localizedDescription]);
}
// otherwise the world has been fed. Wow, your code must rock.
Conseguimos acessar os erros localizedDescription
porque definimos um valor para NSLocalizedDescriptionKey
.
O melhor lugar para obter mais informações é a documentação da Apple . É realmente bom.
Há também um tutorial simples e agradável sobre Cocoa Is My Girlfriend .
id
para aBOOL
. Qualquer leve variação compatível com ARC seria muito apreciada.BOOL
. RetorneNO
em caso de erro e, em vez de verificar o valor de retorno, basta verificarerror
. Senil
seguir em frente, se!= nil
lidar com isso.**error
se não é nulo. Caso contrário, o programa lançará um erro que é completamente hostil e não torna aparente o que está acontecendo.Gostaria de adicionar mais algumas sugestões com base na minha implementação mais recente. Eu olhei para alguns códigos da Apple e acho que meu código se comporta da mesma maneira.
As postagens acima já explicam como criar objetos NSError e devolvê-los, para não me preocupar com essa parte. Vou apenas tentar sugerir uma boa maneira de integrar erros (códigos, mensagens) em seu próprio aplicativo.
Eu recomendo criar um cabeçalho que seja uma visão geral de todos os erros do seu domínio (por exemplo, aplicativo, biblioteca etc.). Meu cabeçalho atual é assim:
FSError.h
FSError.m
Agora, ao usar os valores acima para erros, a Apple criará uma mensagem de erro padrão básica para seu aplicativo. Um erro pode ser criado como o seguinte:
A mensagem de erro padrão gerada pela Apple (
error.localizedDescription
) para o código acima será semelhante à seguinte:Error Domain=com.felis.myapp Code=1002 "The operation couldn’t be completed. (com.felis.myapp error 1002.)"
O exposto acima já é bastante útil para um desenvolvedor, pois a mensagem exibe o domínio em que o erro ocorreu e o código de erro correspondente. Os usuários finais não têm idéia do
1002
significado do código de erro , então agora precisamos implementar algumas boas mensagens para cada código.Para as mensagens de erro, precisamos manter a localização em mente (mesmo que não implementemos mensagens localizadas imediatamente). Eu usei a seguinte abordagem no meu projeto atual:
1) crie um
strings
arquivo que conterá os erros. Arquivos de strings são facilmente localizáveis. O arquivo pode ter a seguinte aparência:FSError.strings
2) Adicione macros para converter códigos inteiros em mensagens de erro localizadas. Eu usei 2 macros no meu arquivo Constants + Macros.h. Eu sempre incluo esse arquivo no cabeçalho do prefixo (
MyApp-Prefix.pch
) por conveniência.Constantes + Macros.h
3) Agora é fácil mostrar uma mensagem de erro amigável com base em um código de erro. Um exemplo:
fonte
Constants+Macros.h
e importo esse arquivo no cabeçalho do prefixo (.pch
arquivo) para que fique disponível em qualquer lugar. Se você quer dizer que está usando apenas uma das duas macros, isso pode funcionar. Talvez a conversão deint
paraNSString
não seja realmente necessária, embora eu não tenha testado isso..strings
arquivo), pois é para lá que a macro da Apple ficará. Leia sobre como usarNSLocalizedStringFromTable
aqui: developer.apple.com/library/mac/documentation/cocoa/conceptual/…FS_ERROR_LOCALIZED_DESCRIPTION
verifica a cadeia localizável em um arquivo chamadoFSError.strings
. Você pode conferir o guia de localização da Apple em.strings
arquivos, se isso lhe for estranho.Ótima resposta Alex. Um problema em potencial é a desreferência nula. Referência da Apple sobre como criar e retornar objetos NSError
fonte
Objetivo-C
Swift 3
fonte
Consulte o seguinte tutorial
Espero que seja útil para você, mas antes você precisa ler a documentação do NSError
Este é um link muito interessante que encontrei recentemente ErrorHandling
fonte
Tentarei resumir a ótima resposta de Alex e o argumento do jlmendezbonini, adicionando uma modificação que tornará tudo compatível com o ARC (até agora não é porque o ARC irá reclamar, pois você deve retornar
id
, o que significa "qualquer objeto", masBOOL
não é um objeto tipo).Agora, em vez de verificar o valor de retorno de nossa chamada de método, verificamos se
error
ainda estánil
. Se não for, temos um problema.fonte
Outro padrão de design que eu já vi envolve o uso de blocos, o que é especialmente útil quando um método está sendo executado de forma assíncrona.
Digamos que tenhamos os seguintes códigos de erro definidos:
Você definiria seu método que pode gerar um erro da seguinte maneira:
E quando você o chama, não precisa se preocupar em declarar o objeto NSError (a conclusão do código fará isso por você) ou em verificar o valor retornado. Você pode fornecer apenas dois blocos: um que será chamado quando houver uma exceção e outro que será chamado quando for bem-sucedido:
fonte
Bem, está um pouco fora do escopo da pergunta, mas, caso você não tenha uma opção para o NSError, sempre poderá exibir o erro de nível baixo:
fonte
que posso usar
NSError.defaultError()
sempre que não tiver um objeto de erro válido.fonte