Pergunta

Eu estou trabalhando em portar uma base de código Java para Cocoa / Objective-C para uso no desktop de código Mac OS X. O Java possui muitos e muitos de métodos com verificada excepções, como:

double asNumber() throws FooException {
    ...
}

Qual é a melhor maneira de representar estes em Objective-C? Exceções ou erro de parâmetros?

- (CGFloat)asNumber { 
    ... // possibly [FooException raise:format:];
}

ou

- (CGFloat)asNumberError:(NSError **)outError {
    ...
}

Eu tenho a sensação de que fora-erros são geralmente a melhor solução para Objective-C, mas como você pode ver ... um monte de métodos como o descrito acima será bastante desajeitado. E, novamente, há muitos destes.

É claro que ter em mente que uma vez que estes são verificados exceções em Java, eu preciso adicionar qualquer blocos @try ou cheques if (*outError) {...} onde quer que esses métodos são chamados ( muitos de lugares).

Lembro-me de ouvir que ao entrar blocos @try era uma vez caro em Objective-C, é barato em 64 bits ou SL ou alguma outra nova env (não me lembro exatamente). Eu não estou nada preocupado com a compatibilidade com versões anteriores, assim que eu sou definitivamente disposta a projetar apenas para o hotness novo.

Foi útil?

Solução

Você deve definitivamente evitar exceções para coisas como analisar números de cordas. Em Objective-C, exceções representam erro do programador, não erro de entrada do usuário, ou até mesmo arquivos indisponíveis. (Parte da razão é que a manipulação de exceção é sempre mais caro e complexo do que mais o tratamento de erros "convencional". Independentemente do fato de que entrar blocos @try é 'custo zero' em 64-bit , ainda é lento, sempre que uma exceção é realmente levantada. ) claro, você está autorizado a exceções usar como quiser, mas não é a maneira de cacau, e você vai encontrar-se em desacordo com outro código Objective-C. As pessoas que usam o seu código será extremamente irritado que você lançar exceções em casos que deve apenas resultar em um erro.

A partir próprios docs da Apple :

"Em muitos ambientes, o uso de exceções é bastante comum. Por exemplo, você pode lançar uma exceção para sinalizar que uma rotina não pôde executar normalmente como quando um arquivo está ausente ou dados não puderam ser analisados ??corretamente . as exceções estão em Objective-C intensivo de recursos. você não deve usar exceções para controle de fluxo geral, ou simplesmente para significar erros. em vez disso, você deve usar o valor de retorno de um método ou função para indicar que ocorreu um erro, e fornecer informações sobre o problema em um objeto de erro ".

olhar como classes internas do Cacau lidar com erros como este. Por exemplo, NSString tem métodos como -floatValue que o retorno 0 se Falha. A melhor solução para sua situação particular pode ser como NSScanner faz -lo, como em -scanFloat: -. aceitar um ponteiro para o campo onde o resultado deve ser armazenado, e YES retorno ou NO baseado em se a análise foi bem sucedida

Além de convenção objectivo n.o-C e as melhores práticas, NSError é muito mais robusto e flexível do que NSException, e permite que o chamador efetivamente ignorar o problema, se quiserem. Eu sugiro a leitura através do Tratamento de erro Guia de Programação Para Cacau . Nota: Se você aceitar uma param NSError**, eu sugiro fortemente que você também projetar para permitir que o cliente para passar NULL se eles não querem receber qualquer informação de erro. Cada Cacau classe Estou ciente faz isso para erros, incluindo NSString.

Embora o código portado pode acabar parecendo totalmente diferente do código Java, reconhecer que ele vai ser usado pelo código Objective-C, não os mesmos clientes do equivalente Java. Definitivamente corresponder as expressões idiomáticas da língua. A porta não será uma imagem espelhada do código Java, mas será muito mais correto (para Objective-C) como resultado.

Outras dicas

Em cacau, as exceções são realmente só deveria ser usado para "erros de programação"; a filosofia é deixar a captura aplicativo los, dar ao usuário a opção de salvar o que estão fazendo, e saia. Por um lado, nem todos os enquadramentos ou caminhos de código pode ser 100% de exceção-safe, então este pode ser o único caminho seguro de ação. Para erros que podem ser esperados e recuperados, você deve usar NSError, normalmente através de um parâmetro para fora.

Você está correto que "os erros são geralmente a melhor solução para ObjC". Muito raramente você vai encontrar uma API em Cocoa que lança uma exceção (a menos que você não tiver satisfeito as condições prévias para a API, mas, nesse caso, o comportamento é indefinido por padrão).

Se você espera que este código para viver além de você e ser adotada por outros desenvolvedores de cacau, eu recomendo usar os erros. Eu trabalho no código que foi construído por pessoas não familiarizadas com Cacau e que usou exceções liberalmente, e eles são uma dor real para trabalho ao redor.

Eu sou um grande fã da abordagem de erro a que usos Objective-C. Você tem que lidar com exceções, mas você pode optar por ignorar os erros se você quiser. Tudo se encaixa com a atitude Objective-C que "o programador sabe o que está fazendo." Ele também faz Objective-C uma linguagem muito limpo para o futuro, porque seu código não está cheio de blocos try-catch.

Dito isso - você pode querer considerar: Existem cenários em que as exceções são ignorados? São as exceções que você joga realmente crítica ? Você encontra-se escrevendo blocos catch simples que as variáveis ??a limpeza e continuar? Eu inclinar-se para fora erros, porque eu como as exceções de sintaxe e Objective-C reservas para apenas os erros mais críticos.

Seus olhares como estes exceções verificadas mapa mais limpa para os erros. Exceções ainda pode ser usado, mas deve ser reservado para casos excepcionais.

As exceções são, provavelmente, a melhor abordagem, como o 64-bit Obj-C ABI (runtime) usa zero de exceções de custos, de modo a obter um código mais limpo, sem nenhum custo real. É claro que em 32 bits os velhos setjmp / longjmp exceções ainda estão em uso e eles não interagem com C ++ por isso, se isso é uma meta, então você tem um problema.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top