[Resolu]Exceptions

PisixPisix Membre
février 2013 modifié dans API UIKit #1
Bonjour,

J'aimerais savoir , Est-il possible de capturer et de lever des exceptions en Objective-C comme celà  se fait en Java???

Réponses

  • Salut,



    https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/RaisingExceptions.html



    Apple déconseille l'utilisation des exceptions en objective C, donc à  éviter.
  • Ah ok coool



    Ah bon image/huh.gif' class='bbc_emoticon' alt='???' /> deconseilléimage/huh.gif' class='bbc_emoticon' alt='???' />??
  • [font=Arial,]Important: Exceptions are resource-intensive in Objective-C. You should not use exceptions for general flow-control, or simply to signify errors (such as a file not being accessible)[/font]



    Important: In many environments, use of exceptionsisfairly commonplace. For example, you mightthrow

    an exception to signalthat a routine could not execute normally"such as when a file is missing or data

    couldnotbeparsedcorrectly.Exceptionsareresource-intensiveinObjective-C.Youshouldnotuseexceptions

    for general flow-control, orsimply to signify errors. Instead you should use the return value of a method or

    functiontoindicatethatanerrorhasoccurred,andprovideinformationabouttheprobleminanerrorobject.

    For more information,see ErrorHandling ProgrammingGuide For Cocoa
  • jpimbertjpimbert Membre
    février 2013 modifié #5
    'samir2303' a écrit:


    Apple déconseille l'utilisation des exceptions en objective C, donc à  éviter.


    Ce n'est pas tout à  fait vrai. Apple recommande de réserver l'usage des exceptions aux erreurs de programmation (un développeur utilise mal une classe, par exemple).

    Une fois livrée à  un utilisateur, le code ne devrait plus lever d'exceptions.
  • mpergandmpergand Membre
    février 2013 modifié #6
    On s'en fout de l'avis d'Apple image/smile.png' class='bbc_emoticon' alt=':)' />

    D'autant qu'il en change comme d' iPhone !



    L'important c'est d'être cohérent, soit on gère les erreurs par exceptions, soit par retour de méthodes, mais pas les deux à  la fois.



    Ce qui était le cas au début de Cocoa, par ex avec NSImage dont les méthodes initWith... pouvaient retourner nil mais aussi lever une exception ! Ce n'est plus le cas depuis les OSX récents (10.6 ?)



    Apple a donc choisi finalement de gérer les erreurs courantes par retour de méthodes comme par ex:

    + (id)fileHandleForReadingFromURL:(NSURL *)url error:(NSError **)error



    Et c'est plutôt une bonne idée.



    Mais l'important pour ses propres développement c'est de définir un paradigme de programmation pour la gestion d'erreurs et de s'y tenir.



    Néanmoins il reste des situations où les exceptions sont inévitables, comme les erreurs de syntaxe dans les parsers, ici un parser JSON:


    <br />
    -([color=#0033f5]id[/color]) parse<br />
    {<br />
    StringParser* parser=[StringParser stringParserWithString:iJStr];<br />
    [color=#0033f5]id[/color] obj=[color=#0033f5]nil[/color];<br />
    <br />
    [color=#0033f5]@try[/color]<br />
    {<br />
    obj=[[color=#0033f5]self[/color] parseNext:parser];<br />
    }<br />
    [color=#0033f5]@catch[/color] (NSException *exception)<br />
    {<br />
    NSLog([color=#990006]@&quot;JSONParser %@: %@&quot;[/color], [exception name], [exception reason]);<br />
    }<br />
    <br />
    [color=#0033f5]return[/color] obj;<br />
    }<br />
    <br />
    




    Perso j'ai pas trop de cas d'utilisations des exceptions en ObjC, car pour ce genre de choses j'utilise le C++:


    <br />
    EXPValue ExpressionParser::parseExpression([color=#0033f5]const[/color] wideChar* exp)<br />
    {<br />
    ...<br />
    exp=skipSpaces(exp);<br />
    <br />
    [color=#898989][color=#0033f5]if[/color][color=#000000](*exp==[/color][color=#1429cc]0[/color][color=#000000]) [/color]// expression vide[/color]<br />
    [color=#0033f5]throw[/color] EXPException(EXPError_InvalidExpression);<br />
    <br />
    EXPValue resultValue;<br />
    <br />
    parseExpression(exp, &amp;resultValue,postOps);<br />
    <br />
    [color=#0033f5]if[/color](resultValue.type==EXPValueType_Number)<br />
    {<br />
    [color=#0033f5]if[/color](isnan(resultValue.number()))<br />
    [color=#0033f5]throw[/color] EXPException(EXPError_NaN);<br />
    <br />
    [color=#0033f5]if[/color](isinf(resultValue.number()))<br />
    [color=#0033f5]throw[/color] EXPException(EXPError_Infinity);<br />
    }<br />
    <br />
    aLastResultValue=resultValue;<br />
    <br />
    ...<br />
    




    C'est vraiment l'utilisation basique des exceptions, tellement basique que ça ressemble furieusement à  l'utilisation des longjmp en C:
    <br />
    in ParseExp([color=#0033f5]char[/color]* exp, EXPVAL* val)<br />
    {<br />
    [color=#0033f5]int[/color] jmpErr;<br />
    <br />
    [color=#0033f5]if[/color](jmpErr=setjmp(jmpEnv))  // interception de l&#39;erreur<br />
    [color=#898989][color=#000000]{ [/color]// erreur[/color]<br />
    [color=#0033f5]return[/color] jmpErr;<br />
    }<br />
    <br />
    ...<br />
    <br />
    // exemple d&#39;utilisation de longjmp<br />
    <br />
    EXPVAL calcForOP(EXPVAL v1, EXPVAL v2, OPType op)<br />
    {<br />
    EXPVAL val;<br />
    <br />
    [color=#0033f5]switch[color=#000000](op)[/color][/color]<br />
    {<br />
    [color=#0033f5]case[/color] OP_Mul:<br />
    val=v1*v2;<br />
    [color=#0033f5]break[color=#000000];[/color][/color]<br />
    <br />
    [color=#0033f5]case[/color] OP_Div:<br />
    [color=#898989][color=#0033f5]if[/color][color=#000000](v2==[/color][color=#1429cc]0[/color][color=#000000]) [/color]// division par zéro &#33;[/color]<br />
    longjmp(jmpEnv,ExpParserError_ZeroDivision);<br />
    <br />
    val=v1/v2;<br />
    [color=#0033f5]break[color=#000000];[/color][/color]<br />
    ...<br />
    




    En conclusion: tu peux suivre les recommandations d'Apple, mais c'est pas le plus important, l'important c'est de faire une interface de programmation cohérente pour l'ensemble de tes classes.
  • zoczoc Membre
    'mpergand' a écrit:


    On s'en fout de l'avis d'Apple image/smile.png' class='bbc_emoticon' alt=':)' />

    D'autant qu'il en change comme d' iPhone !


    Non, on ne s'en fout pas, surtout si on utilise ARC, car ARC + Exceptions = Leaks...



    http://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions
  • mpergandmpergand Membre
    mars 2013 modifié #8
    'zoc' a écrit:


    Non, on ne s'en fout pas, surtout si on utilise ARC, car ARC + Exceptions = Leaks...




    M'en fout, je n'utilise pas ARC image/kiss.gif' class='bbc_emoticon' alt=':-*' />



    La solution, c'est de limiter l'utilisation des exceptions à  la gestion interne à  une classe. Ces exceptions ne doivent pas remonter au niveau du programme appelant.


    For example, a parsing library might use exceptions internally to indicate problems and enable a quick exit from a parsing state that could be deeply recursive; however, you should take care to catch such exceptions at the top level of the library and translate them into an appropriate return code or state.




    Il se trouve que c'est exactement ce que fait dans mon parser JSON cité plus haut:


    <br />
    JSONParser* jParser=[[JSONParser alloc] initWithString:jsStr];<br />
    <br />
    id o=[jParser parse];<br />
    NSLog(@&quot;%@&quot;,o);<br />
    <br />
    <br />
    NSString* js=[jParser createWithObject:o];<br />
    NSLog(@&quot;\n%@&quot;,js);<br />
    



    <br />
    -(id) parse<br />
    {<br />
    StringParser* parser=[StringParser stringParserWithString:iJStr];<br />
    id obj=nil;<br />
    @try<br />
      {<br />
      obj=[self parseNext:parser];<br />
      }<br />
    @catch (NSException *exception)<br />
      {<br />
      NSLog(@&quot;JSONParser %@: %@&quot;, [exception name], [exception reason]);<br />
      }<br />
    <br />
    return obj;<br />
    }<br />
    <br />
    -(NSString*) createWithObject:(id) o<br />
    {<br />
    <br />
    NSString* str=nil;<br />
    <br />
    @try<br />
      {<br />
      str= [self create:o];<br />
      }<br />
    @catch (NSException *exception)<br />
      {<br />
      NSLog(@&quot;JSON create %@: %@&quot;, [exception name], [exception reason]);<br />
      }<br />
    <br />
    return str;<br />
    }<br />
    




    C'est deux méthodes retournent nil en cas d'erreurs.
Connectez-vous ou Inscrivez-vous pour répondre.