Vos macros les plus utiles

AliGatorAliGator Membre, Modérateur
août 2012 modifié dans Objective-C, Swift, C, C++ #1
Hello,



Je commence un nouveau sujet pour partager quelques macros que j'utilise de plus en plus et que je trouve très utiles.

Par exemple, depuis que j'ai découvert la macro _Pragma(x) pour générer des #pragma à  la volée uniquement quand la macro est déroulée, j'en ai trouvé des usages très pratiques :


#define GENERATE_PRAGMA(x) _Pragma(#x)<br />
#define TODO(x) GENERATE_PRAGMA(message(&quot;[TODO] &quot; #x))<br />
#define FIXME(x) GENERATE_PRAGMA(message(&quot;[FIXME] &quot; #x))<br />
#define NOTE(x) GENERATE_PRAGMA(message(&quot;[NOTE] &quot; #x))<br />
#define MAGIC_NUMBER FIXME(Replace magic number with constant)<br />
#define NOT_IMPLEMENTED(warningMessage...) [[[[UIAlertView alloc] initWithTitle:@&quot;Not implemented&quot; &#092;<br />
	message:[NSString stringWithFormat:@&quot;%s&quot;,__PRETTY_FUNCTION__] &#092;<br />
	delegate:nil cancelButtonTitle:@&quot;OK&quot; otherButtonTitles:nil] autorelease] show]; &#092;<br />
	TODO(Implement this - warningMessage)


Avantage de ces macros, c'est que ça génère un type de warning/message différent des autres, que l'on peut facilement filtrer en triant tes warnings par type, et en plus ça a un préfixe commun ([TODO] ou [FIXME] ou [NOTE]) qui permet en plus de savoir de quoi il retourne, de les isoler facilement.



Exemple d'utilisation :
- (IBAction)testAction<br />
{<br />
	NOT_IMPLEMENTED(This action should show the next screen);<br />
}<br />
- (void)centerHorizontally<br />
{<br />
	TODO(Check if this method is called every time the view width change)<br />
	CGRect rect = self.view.frame;<br />
	rect.origin.x = (320 - rect.size.width) / 2; MAGIC_NUMBER<br />
	self.view.frame = rect;<br />
}


Cela va me générer 3 warnings propres, et si j'exécute l'action testAction cela va même me mettre une UIAlertView pour indiquer à  l'utilisateur que l'action n'est pas encore codée image/smile.png' class='bbc_emoticon' alt=':)' />
«1

Réponses

  • Intéressant...

    Vers la fin du projet, j'mets un UIAlertView au démarrage...
  • AliGatorAliGator Membre, Modérateur
    Heu ? Pas bien compris le coup de ton UIAlertView au démarrage et le rapport avec le sujet ?
  • Pardon, fatigué hier soir...

    Pour ma ToDoList, j'ai pris l'habitude d'une UIAlertView...

    Mais j'vais voir de plus près ta macro...
  • muqaddarmuqaddar Administrateur
    Sa macro permet de mettre des TODO un peu partout dans le code, ce qui est bien différent.
  • gilvgilv Membre
    Salut,



    Ca a l'air sympa ... je vais tester ça. Tu peux mettre le define pour NOT_IMPLEMENTED.



    Merci.
  • 'muqaddar' a écrit:


    Sa macro permet de mettre des TODO un peu partout dans le code, ce qui est bien différent.


    C'est pour ça que je vais y jeter un oe“il...
  • AliGatorAliGator Membre, Modérateur
    août 2012 modifié #8
    'Larme' a écrit:


    Pour ma ToDoList, j'ai pris l'habitude d'une UIAlertView...

    Mais j'vais voir de plus près ta macro...
    Ah ok... j'avais cru décoder que tu voulais dire ça mais c'est le "à  la fin de mon projet" qui m'a fait croire que j'avais mal compris... car les TODO, on les met au début du projet, quand il reste des trucs à  faire, pas à  la fin quand tout est fait ^^
    'muqaddar' a écrit:


    Sa macro permet de mettre des TODO un peu partout dans le code, ce qui est bien différent.
    En effet cela n'a rien à  voir.

    Mettre des UIAlertView ça a plusieurs inconvénients :
    • C'est verbeux à  écrire pour chaque TODO
    • Tu ne peux pas facilement voir s'il te reste encore beaucoup de choses à  faire / à  implémenter par une recherche, car tu as certainement des UIAlertView autre part qui n'ont rien à  voir avec des alertes de TODO donc tout sera mélangé
    • Mais surtout ça ne mentionne les TODO qu'à  l'exécution. Il faut que tu déclenches l'action pour avoir l'UIAlertView, donc que tu passes par le chemin non implémenté pour avoir l'alerte qui te dit que ce n'est pas implémenté. C'est un peu ce que fait ma macro NOT_IMPLEMENTED, ça le signale au Runtime (sauf que ma macro met aussi un warning en plus)


    L'avantage de mes macros c'est que ça met des warnings, donc tu les vois à  la compilation, et non pas à  l'exécution. Donc tu peux pas les louper, et pas besoin d'exécuter ton appli et de passer par tous les chemins / cas d'usage pour vérifier que tu as implémenté tout ce qu'il te restait à  faire !
    'gilv' a écrit:


    Ca a l'air sympa ... je vais tester ça. Tu peux mettre le define pour NOT_IMPLEMENTED.
    Ah oui en effet oubli de ma part, bien vu ! J'ai édité mon post plus haut pour la rajouter image/smile.png' class='bbc_emoticon' alt=':)' />
  • Très intéressant ce topic, je suis en train de reprendre les macro qu'Ali à  partagé pour ajouter le support OS X / iOS, voici ce que j'ai modifié :


    <br />
    <br />
    [color=#78492A][font=Menlo][size=2]<br />
    #define NOT_IMPLEMENTED(warningMessage) ALERT_BOX(@[color=#d12f1b]&quot;Not implemented&quot;[/color], [NSString stringWithFormat:@[color=#d12f1b]&quot;%s: %s&quot;[/color],__PRETTY_FUNCTION__, warningMessage]); \[/size][/font][/color][color=#78492A][font=Menlo][size=2]<br />
    TODO(Implement this - warningMessage)[/size][/font][/color]<br />
    <br />
    <br />
    [color=#bb2ca2]void[/color] ALERT_BOX([color=#703daa]NSString[/color] *title, [color=#703daa]NSString[/color]* message) {<br />
    #if TARGET_OS_IPHONE<br />
    [[[[UIAlertView alloc] initWithTitle:title<br />
    message:message<br />
    delegate:[color=#bb2ca2]nil[/color] cancelButtonTitle:[color=#d12f1b]@&quot;OK&quot;[/color] otherButtonTitles:[color=#bb2ca2]nil[/color]] autorelease] show];<br />
    #else[color=#3D1D81]<br />
    [color=#000000][[[/color][color=#703daa]NSAlert[/color][color=#000000] [/color]alertWithMessageText[color=#000000]:title [/color]defaultButton[color=#000000]:[/color][color=#d12f1b]@&quot;OK&quot;[/color][color=#000000] [/color]alternateButton[color=#000000]:[/color][color=#bb2ca2]nil[/color][color=#000000] [/color]otherButton[color=#000000]:[/color][color=#bb2ca2]nil[/color][color=#000000] [/color]informativeTextWithFormat[color=#000000]:[/color][color=#d12f1b]@&quot;%@&quot;[/color][color=#000000], message] [/color]runModal[color=#000000]];[/color][/color]<br />
    #endif<br />
    }<br />
    
  • Et dans un autre domaine, étant grand fan de NSLogger, voici mes macro custom qui se servent de son API :


    <br />
    #pragma mark NSLogger<br />
    #ifdef DEBUG<br />
    #define LOG_NETWORK(level, ...)    LogMessageF(__FILE__,__LINE__,__FUNCTION__,@&quot;network&quot;,level,__VA_ARGS__)<br />
    #define LOG_GENERAL(level, ...)    LogMessageF(__FILE__,__LINE__,__FUNCTION__,@&quot;general&quot;,level,__VA_ARGS__)<br />
    #define LOG_GRAPHICS(level, ...)   LogMessageF(__FILE__,__LINE__,__FUNCTION__,@&quot;graphics&quot;,level,__VA_ARGS__)<br />
    #define LOG_NETWORK_CRITICAL(...) LOG_NETWORK(0, [NSString stringWithFormat:@&quot;ALERT " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_ERROR(...)  LOG_NETWORK(1, [NSString stringWithFormat:@&quot;ERROR " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_WARNING(...) LOG_NETWORK(2, [NSString stringWithFormat:@&quot;WARNING " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_NOTICE(...)  LOG_NETWORK(3, [NSString stringWithFormat:@&quot;NOTICE " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_INFO(...)  LOG_NETWORK(4, [NSString stringWithFormat:@&quot;INFO " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_DEBUG(...)  LOG_NETWORK(5, [NSString stringWithFormat:@&quot;DEBUG " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_CRITICAL(...) LOG_GENERAL(0, [NSString stringWithFormat:@&quot;ALERT " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_ERROR(...)  LOG_GENERAL(1, [NSString stringWithFormat:@&quot;ERROR " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_WARNING(...) LOG_GENERAL(2, [NSString stringWithFormat:@&quot;WARNING " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_NOTICE(...)  LOG_GENERAL(3, [NSString stringWithFormat:@&quot;NOTICE " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_INFO(...)  LOG_GENERAL(4, [NSString stringWithFormat:@&quot;INFO " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_DEBUG(...)  LOG_GENERAL(5, [NSString stringWithFormat:@&quot;DEBUG " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_CRITICAL(...) LOG_GRAPHICS(0, [NSString stringWithFormat:@&quot;ALERT " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_ERROR(...)  LOG_GRAPHICS(1, [NSString stringWithFormat:@&quot;ERROR " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_WARNING(...) LOG_GRAPHICS(2, [NSString stringWithFormat:@&quot;WARNING " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_NOTICE(...) LOG_GRAPHICS(3, [NSString stringWithFormat:@&quot;NOTICE " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_INFO(...)  LOG_GRAPHICS(4, [NSString stringWithFormat:@&quot;INFO " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_DEBUG(...)  LOG_GRAPHICS(5, [NSString stringWithFormat:@&quot;DEBUG " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #else<br />
    #define LOG_NETWORK(...)    do{}while(0)<br />
    #define LOG_GENERAL(...)    do{}while(0)<br />
    #define LOG_GRAPHICS(...)   do{}while(0)<br />
    #define LOG_NETWORK_CRITICAL(...) do{}while(0)<br />
    #define LOG_NETWORK_ERROR(...)  do{}while(0)<br />
    #define LOG_NETWORK_WARNING(...) do{}while(0)<br />
    #define LOG_NETWORK_NOTICE(...)  do{}while(0)<br />
    #define LOG_NETWORK_INFO(...)  do{}while(0)<br />
    #define LOG_NETWORK_DEBUG(...)  do{}while(0)<br />
    #define LOG_GENERAL_CRITICAL(...) do{}while(0)<br />
    #define LOG_GENERAL_ERROR(...)  do{}while(0)<br />
    #define LOG_GENERAL_WARNING(...) do{}while(0)<br />
    #define LOG_GENERAL_NOTICE(...)  do{}while(0)<br />
    #define LOG_GENERAL_INFO(...)  do{}while(0)<br />
    #define LOG_GENERAL_DEBUG(...)  do{}while(0)<br />
    #define LOG_GRAPHICS_CRITICAL(...) do{}while(0)<br />
    #define LOG_GRAPHICS_ERROR(...)  do{}while(0)<br />
    #define LOG_GRAPHICS_WARNING(...) do{}while(0)<br />
    #define LOG_GRAPHICS_NOTICE(...) do{}while(0)<br />
    #define LOG_GRAPHICS_INFO(...)  do{}while(0)<br />
    #define LOG_GRAPHICS_DEBUG(...)  do{}while(0)<br />
    #endif<br />
    #if defined(DEBUG) &amp;&amp; &#33;defined(NDEBUG)<br />
    #undef assert<br />
    #if __DARWIN_UNIX03<br />
    #define assert(e) \<br />
    (__builtin_expect(&#33;(e), 0) ? (CFShow(CFSTR(&quot;assert going to fail, connect NSLogger NOW\n&quot;)), LoggerFlush(NULL,YES), __assert_rtn(__func__, __FILE__, __LINE__, #e)) : (void)0)<br />
    #else<br />
    #define assert(e)  \<br />
    (__builtin_expect(&#33;(e), 0) ? (CFShow(CFSTR(&quot;assert going to fail, connect NSLogger NOW\n&quot;)), LoggerFlush(NULL,YES), __assert(#e, __FILE__, __LINE__)) : (void)0)<br />
    #endif<br />
    #endif<br />
    
  • StephSteph Membre
    août 2012 modifié #11
    Ali tu mets ça dans ton fichier prefix je suppose ?
  • AliGatorAliGator Membre, Modérateur
    Heu je suppose que par "fichier prefix" tu veux parler du fichier "PCH" (PCH qui veut dire "Pre-Compiled Header") ?



    Alors oui et non : je met ça dans un fichier Macros.h. Et c'est ce fichier Macros.h que je #import dans mon fichier PCH.

    Ce qui me permet d'avoir un fichier Macros.h partagé par mes projets, utilisé par mes templates de projet et aussi versionné.
  • Ca ne te déprime pas de voir tout ce qu'il te reste à  faire à  chaque fois que tu compiles ?

  • AliGatorAliGator Membre, Modérateur
    Non car

    1) Je peux les désactiver facilement

    2) Justement, de par ma politique/volonté de zero-warnings, ça me force un peu à  régler ces warnings qui sinon polluent un peu ma vue ^^



    C'est un peu comme une TODO-List : quand tu fais une liste de toutes les choses que tu as à  faire, tu peux le prendre du côté déprimant "purée j'ai tout ça à  faire" ou tu peux le prendre du côté jouissif à  chaque fois que tu enlèves des éléments de la liste "ahah ça c'est fait, ma liste diminue je vais en venir à  bout"



    Par expérience, si mon met pas ces TODO, on oublie toujours de faire des trucs. Même si on s'est dit dans un coin de notre tête "tiens faudra que je pense à  fignoler ça un jour", au final on le fait jamais car ça passe à  la trappe.

    Ou alors on met des commentaires dans le code pour y penser, mais on les relis jamais (et comme, contrairement aux macros qui doivent contenir le mot exact TODO avec la syntaxe, dans les commentaire on peut un peu écrire ce qu'on veut, on risque fort de ne pas écrire le même mot clé dans tous les commentaires, parfois "TODO" parfois "TO-DO", parfois "[TODO]"...



    Qui n'a jamais vu des code source avec des commentaires dedans du genre "Temporary Fix" ou "Patch temporaire pour contourner tel bug, à  régler plus tard"... commentaires qui datent de 2 ans ou plus parce que finalement personne ne les a fixés et qu'au lieu d'une petite rustine temporaire "le temps de finir" c'est devenu la solution crade permanente.



    Certes en mettant ce genre de macros type TODO dans le code cela génère plein de warnings. Mais justement ça te force à  les régler. Alors que sinon ils passent forcément à  la trappe, c'est assuré.
  • psychoh13psychoh13 Mothership Developer Membre
    @AliGator je pense que tu peux améliorer ta macro MAGIC_NUMBER de la sorte:
    <br />
    #define MAGIC_NUMBER(x) (({ FIXME(Replace magic number x with constant) }), x)<br />
    




    Ainsi tu peux spécifiquement encadrer la valeur ou l'expression qui nécessite d'être remplacée.



    Voilà  deux petites fonctions/macros que j'aime bien utiliser:
    <br />
    static inline const char *BOOL_STR(BOOL v) { return (v ? &quot;YES&quot; : &quot;NO&quot;); }<br />
    static inline id BOOL_OBJ(BOOL v) { return (__bridge id)(v ? kCFBooleanTrue : kCFBooleanFalse); }<br />
    
  • psychoh13psychoh13 Mothership Developer Membre
    'yoann' a écrit:


    Et dans un autre domaine, étant grand fan de NSLogger, voici mes macro custom qui se servent de son API :


    <br />
    #pragma mark NSLogger<br />
    #ifdef DEBUG<br />
    #define LOG_NETWORK(level, ...)	LogMessageF(__FILE__,__LINE__,__FUNCTION__,@&quot;network&quot;,level,__VA_ARGS__)<br />
    #define LOG_GENERAL(level, ...)	LogMessageF(__FILE__,__LINE__,__FUNCTION__,@&quot;general&quot;,level,__VA_ARGS__)<br />
    #define LOG_GRAPHICS(level, ...)   LogMessageF(__FILE__,__LINE__,__FUNCTION__,@&quot;graphics&quot;,level,__VA_ARGS__)<br />
    #define LOG_NETWORK_CRITICAL(...) LOG_NETWORK(0, [NSString stringWithFormat:@&quot;ALERT " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_ERROR(...)  LOG_NETWORK(1, [NSString stringWithFormat:@&quot;ERROR " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_WARNING(...) LOG_NETWORK(2, [NSString stringWithFormat:@&quot;WARNING " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_NOTICE(...)  LOG_NETWORK(3, [NSString stringWithFormat:@&quot;NOTICE " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_INFO(...)  LOG_NETWORK(4, [NSString stringWithFormat:@&quot;INFO " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_NETWORK_DEBUG(...)  LOG_NETWORK(5, [NSString stringWithFormat:@&quot;DEBUG " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_CRITICAL(...) LOG_GENERAL(0, [NSString stringWithFormat:@&quot;ALERT " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_ERROR(...)  LOG_GENERAL(1, [NSString stringWithFormat:@&quot;ERROR " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_WARNING(...) LOG_GENERAL(2, [NSString stringWithFormat:@&quot;WARNING " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_NOTICE(...)  LOG_GENERAL(3, [NSString stringWithFormat:@&quot;NOTICE " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_INFO(...)  LOG_GENERAL(4, [NSString stringWithFormat:@&quot;INFO " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GENERAL_DEBUG(...)  LOG_GENERAL(5, [NSString stringWithFormat:@&quot;DEBUG " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_CRITICAL(...) LOG_GRAPHICS(0, [NSString stringWithFormat:@&quot;ALERT " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_ERROR(...)  LOG_GRAPHICS(1, [NSString stringWithFormat:@&quot;ERROR " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_WARNING(...) LOG_GRAPHICS(2, [NSString stringWithFormat:@&quot;WARNING " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_NOTICE(...) LOG_GRAPHICS(3, [NSString stringWithFormat:@&quot;NOTICE " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_INFO(...)  LOG_GRAPHICS(4, [NSString stringWithFormat:@&quot;INFO " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #define LOG_GRAPHICS_DEBUG(...)  LOG_GRAPHICS(5, [NSString stringWithFormat:@&quot;DEBUG " [%@ %p] " %@&quot;, NSStringFromClass([self class]), self, [[[NSString alloc] initWithFormat:__VA_ARGS__] autorelease]])<br />
    #else<br />
    #define LOG_NETWORK(...)	do{}while(0)<br />
    #define LOG_GENERAL(...)	do{}while(0)<br />
    #define LOG_GRAPHICS(...)   do{}while(0)<br />
    #define LOG_NETWORK_CRITICAL(...) do{}while(0)<br />
    #define LOG_NETWORK_ERROR(...)  do{}while(0)<br />
    #define LOG_NETWORK_WARNING(...) do{}while(0)<br />
    #define LOG_NETWORK_NOTICE(...)  do{}while(0)<br />
    #define LOG_NETWORK_INFO(...)  do{}while(0)<br />
    #define LOG_NETWORK_DEBUG(...)  do{}while(0)<br />
    #define LOG_GENERAL_CRITICAL(...) do{}while(0)<br />
    #define LOG_GENERAL_ERROR(...)  do{}while(0)<br />
    #define LOG_GENERAL_WARNING(...) do{}while(0)<br />
    #define LOG_GENERAL_NOTICE(...)  do{}while(0)<br />
    #define LOG_GENERAL_INFO(...)  do{}while(0)<br />
    #define LOG_GENERAL_DEBUG(...)  do{}while(0)<br />
    #define LOG_GRAPHICS_CRITICAL(...) do{}while(0)<br />
    #define LOG_GRAPHICS_ERROR(...)  do{}while(0)<br />
    #define LOG_GRAPHICS_WARNING(...) do{}while(0)<br />
    #define LOG_GRAPHICS_NOTICE(...) do{}while(0)<br />
    #define LOG_GRAPHICS_INFO(...)  do{}while(0)<br />
    #define LOG_GRAPHICS_DEBUG(...)  do{}while(0)<br />
    #endif<br />
    #if defined(DEBUG) &amp;&amp; &#33;defined(NDEBUG)<br />
    #undef assert<br />
    #if __DARWIN_UNIX03<br />
    #define assert(e) \<br />
    (__builtin_expect(&#33;(e), 0) ? (CFShow(CFSTR(&quot;assert going to fail, connect NSLogger NOW\n&quot;)), LoggerFlush(NULL,YES), __assert_rtn(__func__, __FILE__, __LINE__, #e)) : (void)0)<br />
    #else<br />
    #define assert(e)  \<br />
    (__builtin_expect(&#33;(e), 0) ? (CFShow(CFSTR(&quot;assert going to fail, connect NSLogger NOW\n&quot;)), LoggerFlush(NULL,YES), __assert(#e, __FILE__, __LINE__)) : (void)0)<br />
    #endif<br />
    #endif<br />
    





    Et voici une amélioration des macros de @yoann:


    <br />
    #ifdef DEBUG<br />
    #define LOG_MESSAGE(type, level, levelText, format, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, type, level, levelText @&quot; " [%@ %p] " %@&quot; format, NSStringFromClass([self class]), self, ##__VA_ARGS__)<br />
    #else<br />
    #define LOG_MESSAGE(type, level, levelText, format, ...) do { } while(0)<br />
    #endif<br />
    #define LOG_NETWORK(level, levelText, format, ...)    LOG_MESSAGE(@&quot;network&quot;, level, levelText, format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL(level, levelText, format, ...)    LOG_MESSAGE(@&quot;general&quot;, level, levelText, format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS(level, levelText, format, ...)   LOG_MESSAGE(@&quot;graphics&quot;, level, levelText, format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_CRITICAL(format, ...)  LOG_NETWORK(0, @&quot;ALERT&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_ERROR(format, ...)	 LOG_NETWORK(1, @&quot;ERROR&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_WARNING(format, ...)   LOG_NETWORK(2, @&quot;WARNING&quot;, format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_NOTICE(format, ...)    LOG_NETWORK(3, @&quot;NOTICE&quot; , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_INFO(format, ...)	  LOG_NETWORK(4, @&quot;INFO&quot;   , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_DEBUG(format, ...)	 LOG_NETWORK(5, @&quot;DEBUG&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_CRITICAL(format, ...)  LOG_GENERAL(0, @&quot;ALERT&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_ERROR(format, ...)	 LOG_GENERAL(1, @&quot;ERROR&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_WARNING(format, ...)   LOG_GENERAL(2, @&quot;WARNING&quot;, format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_NOTICE(format, ...)    LOG_GENERAL(3, @&quot;NOTICE&quot; , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_INFO(format, ...)	  LOG_GENERAL(4, @&quot;INFO&quot;   , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_DEBUG(format, ...)	 LOG_GENERAL(5, @&quot;DEBUG&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_CRITICAL(format, ...) LOG_GRAPHICS(0, @&quot;ALERT&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_ERROR(format, ...)    LOG_GRAPHICS(1, @&quot;ERROR&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_WARNING(format, ...)  LOG_GRAPHICS(2, @&quot;WARNING&quot;, format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_NOTICE(format, ...)   LOG_GRAPHICS(3, @&quot;NOTICE&quot; , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_INFO(format, ...)	 LOG_GRAPHICS(4, @&quot;INFO&quot;   , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_DEBUG(format, ...)    LOG_GRAPHICS(5, @&quot;DEBUG&quot;  , format, ##__VA_ARGS__)<br />
    




    Elles prennent en compte le fait que LogMessageF() prends un format comme dernier argument. Ce changement est plus qu'une amélioration c'est important, car si la NSString générée par ton format contient un % mal placé tu vas avoir des surprises.

    Dans cette version tu n'auras pas ce problème. De plus, elles prennent moins de place.
  • FKDEVFKDEV Membre
    août 2012 modifié #17
    C'est une bonne idée en tous cas (la TODO).

    L'avantage par rapport a la feuille de papier, c'est qu'on peut partager via la gestion de configuration et qu'on est certain que tout le monde va voir les TODO, ce qui n'est pas le cas dUn TODO.TXT planqué dans un coin.



    En plus je ne connaissais pas _Pragma, j'ai bien fait de venir...
  • psychoh13psychoh13 Mothership Developer Membre
    août 2012 modifié #18
    'FKDEV' a écrit:


    C'est une bonne idée en tous cas (la TODO).

    L'avantage par rapport a la feuille de papier, c'est qu'on peut partager via la gestion de configuration et qu'on est certain que tout le monde va voir les TODO, ce qui n'est pas le cas dUn TODO.TXT planqué dans un coin.



    En plus je ne connaissais pas _Pragma, j'ai bien fait de venir...




    Une autre technique qui n'utilise pas les pragma c'est d'utiliser des commentaires comme ceci:
    // TODO: something<br />
    // FIXME: something<br />
    // MARK: something<br />
    




    L'inconvénient c'est que tu n'as pas de warning pour ça, mais l'avantage c'est qu'il s'affiche dans le menu des symboles de ton fichier donc tu peux y aller directement.
  • AliGatorAliGator Membre, Modérateur
    @psychoh13 : Oui c'est ce que j'utilisais avant, mais je trouve au final que ce n'est pas efficace :

    - On ne va pas si souvent dans le menu des symboles. Enfin si, moi j'y vais souvent, mais ce n'est pas toujours le cas de mes collègues d'une part, et puis on ne pense pas à  y aller POUR voir les TODO et FIXME

    - Tu es obligé d'aller dans chaque fichier pour voir s'il a des TODO ou des FIXME, ce qui est injouable en pratique

    - Note qu'avec les warnings aussi tu peux y aller directement image/tongue.png' class='bbc_emoticon' alt=':P' />
  • psychoh13psychoh13 Mothership Developer Membre
    'AliGator' a écrit:


    @psychoh13 : Oui c'est ce que j'utilisais avant, mais je trouve au final que ce n'est pas efficace :

    - On ne va pas si souvent dans le menu des symboles. Enfin si, moi j'y vais souvent, mais ce n'est pas toujours le cas de mes collègues d'une part, et puis on ne pense pas à  y aller POUR voir les TODO et FIXME

    - Tu es obligé d'aller dans chaque fichier pour voir s'il a des TODO ou des FIXME, ce qui est injouable en pratique

    - Note qu'avec les warnings aussi tu peux y aller directement image/tongue.png' class='bbc_emoticon' alt=':P' />




    Bah tu peux toujours faire une recherche dans le projet image/biggrin.png' class='bbc_emoticon' alt=':D' />
  • AliGatorAliGator Membre, Modérateur
    Ce qui enlève tout l'intérêt de la chose, surtout que :
    • Au final du coup quel intérêt de mettre des marqueurs si c'est pour être obligé de les rechercher. D'autant que tu peux potentiellement tomber sur des utilisations de ces mots clés en dehors de leur contexte genre dans une NSString ou autre.
    • Un des plus gros problèmes de mettre des TODO/FIXME en commentaires également : tu n'es pas à  l'abri d'une coquille et de risquer de mal écrire le mot clé, il n'y a aucun contrôle. Si tu écris FICME au lieu de FIXME, tu risques pas de le retrouver par une recherche. Avec une macro si tu fais une faute le compilo va te le dire image/wink.png' class='bbc_emoticon' alt=';)' />
    • En pratique on sait très bien tu vas oublier de faire ladite recherche à  la fin du projet. Alors qu'avec des warnings, tu vas être obligé de les prendre en compte. C'est à  mon sens le plus gros avantage


    Car en pratique on sait très bien ce qui se passe au fur et à  mesure de l'avancée d'un projet sinon... à  la fin plus personne ne recherche les TODO ou FIXME pour penser à  les corriger.
  • 'psychoh13' a écrit:


    Et voici une amélioration des macros de @yoann:


    <br />
    #ifdef DEBUG<br />
    #define LOG_MESSAGE(type, level, levelText, format, ...) LogMessageF(__FILE__, __LINE__, __FUNCTION__, type, level, levelText @&quot; " [%@ %p] " %@&quot; format, NSStringFromClass([self class]), self, ##__VA_ARGS__)<br />
    #else<br />
    #define LOG_MESSAGE(type, level, levelText, format, ...) do { } while(0)<br />
    #endif<br />
    #define LOG_NETWORK(level, levelText, format, ...)	LOG_MESSAGE(@&quot;network&quot;, level, levelText, format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL(level, levelText, format, ...)	LOG_MESSAGE(@&quot;general&quot;, level, levelText, format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS(level, levelText, format, ...)   LOG_MESSAGE(@&quot;graphics&quot;, level, levelText, format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_CRITICAL(format, ...)  LOG_NETWORK(0, @&quot;ALERT&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_ERROR(format, ...)	 LOG_NETWORK(1, @&quot;ERROR&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_WARNING(format, ...)   LOG_NETWORK(2, @&quot;WARNING&quot;, format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_NOTICE(format, ...)	LOG_NETWORK(3, @&quot;NOTICE&quot; , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_INFO(format, ...)	  LOG_NETWORK(4, @&quot;INFO&quot;   , format, ##__VA_ARGS__)<br />
    #define LOG_NETWORK_DEBUG(format, ...)	 LOG_NETWORK(5, @&quot;DEBUG&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_CRITICAL(format, ...)  LOG_GENERAL(0, @&quot;ALERT&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_ERROR(format, ...)	 LOG_GENERAL(1, @&quot;ERROR&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_WARNING(format, ...)   LOG_GENERAL(2, @&quot;WARNING&quot;, format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_NOTICE(format, ...)	LOG_GENERAL(3, @&quot;NOTICE&quot; , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_INFO(format, ...)	  LOG_GENERAL(4, @&quot;INFO&quot;   , format, ##__VA_ARGS__)<br />
    #define LOG_GENERAL_DEBUG(format, ...)	 LOG_GENERAL(5, @&quot;DEBUG&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_CRITICAL(format, ...) LOG_GRAPHICS(0, @&quot;ALERT&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_ERROR(format, ...)	LOG_GRAPHICS(1, @&quot;ERROR&quot;  , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_WARNING(format, ...)  LOG_GRAPHICS(2, @&quot;WARNING&quot;, format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_NOTICE(format, ...)   LOG_GRAPHICS(3, @&quot;NOTICE&quot; , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_INFO(format, ...)	 LOG_GRAPHICS(4, @&quot;INFO&quot;   , format, ##__VA_ARGS__)<br />
    #define LOG_GRAPHICS_DEBUG(format, ...)	LOG_GRAPHICS(5, @&quot;DEBUG&quot;  , format, ##__VA_ARGS__)<br />
    




    Elles prennent en compte le fait que LogMessageF() prends un format comme dernier argument. Ce changement est plus qu'une amélioration c'est important, car si la NSString générée par ton format contient un % mal placé tu vas avoir des surprises.

    Dans cette version tu n'auras pas ce problème. De plus, elles prennent moins de place.




    Bien vu :-)



    J'ai fait les macro pour moi, de fait je sais comment les utiliser sans chercher plus loin :-)



    Une amélioration intéressante serait d'avoir non pas le nom de la classe d'afficher mais classe d'origine + méthode (cà d éviter d'avoir le nom d'une sous classe) ou si on est pas dans une méthode mais une fonction, le nom de la fonction.



    Si quelqu'un a une combine propre pour ça, je suis preneur.
  • AliGatorAliGator Membre, Modérateur
    C'est pas ce a quoi sert la macro __PRETTY_FUNCTION__ ?
  • psychoh13psychoh13 Mothership Developer Membre
    'yoann' a écrit:






    Bien vu :-)



    J'ai fait les macro pour moi, de fait je sais comment les utiliser sans chercher plus loin :-)



    Une amélioration intéressante serait d'avoir non pas le nom de la classe d'afficher mais classe d'origine + méthode (cà d éviter d'avoir le nom d'une sous classe) ou si on est pas dans une méthode mais une fonction, le nom de la fonction.



    Si quelqu'un a une combine propre pour ça, je suis preneur.




    C'est le principe de __FUNCTION__, __PRETTY_FUNCTION__ et __func__

  • yoannyoann Membre
    août 2012 modifié #25
    'psychoh13' a écrit:


    C'est le principe de __FUNCTION__, __PRETTY_FUNCTION__ et __func__




    Oui c'est le principe en effet (je n'avais cependant pas noté que cela faisait bien le distinguo avec les sous classe). NSLogger permet d'ailleurs de l'afficher d'origine, donc j'ai un peu revu mes macro en adaptant les corrections proposés.



    Pour le moment j'ai ceci :


    <br />
    #ifdef DEBUG<br />
    NSString *LOG_LEVEL_TEXT_FROM_INT(int level);<br />
    #define LOG_MESSAGE(domain, level, ...)  LogMessageF(__FILE__,__LINE__,__FUNCTION__, domain, level, [LOG_LEVEL_TEXT_FROM_INT(level) stringByAppendingFormat:__VA_ARGS__])<br />
    #define LOG_NETWORK(level, ...)	   LOG_MESSAGE(@&quot;network&quot;, level, __VA_ARGS__)<br />
    #define LOG_GENERAL(level, ...)	   LOG_MESSAGE(@&quot;general&quot;, level, __VA_ARGS__)<br />
    #define LOG_GRAPHICS(level, ...)	  LOG_MESSAGE(@&quot;graphics&quot;, level, __VA_ARGS__)<br />
    #define LOG_NETWORK_CRITICAL(...)	  LOG_NETWORK(0, __VA_ARGS__)<br />
    #define LOG_NETWORK_ERROR(...)	   LOG_NETWORK(1, __VA_ARGS__)<br />
    #define LOG_NETWORK_WARNING(...)	  LOG_NETWORK(2, __VA_ARGS__)<br />
    #define LOG_NETWORK_NOTICE(...)	   LOG_NETWORK(3, __VA_ARGS__)<br />
    #define LOG_NETWORK_INFO(...)	   LOG_NETWORK(4, __VA_ARGS__)<br />
    #define LOG_NETWORK_DEBUG(...)	   LOG_NETWORK(5, __VA_ARGS__)<br />
    #define LOG_GENERAL_CRITICAL(...)	  LOG_GENERAL(0, __VA_ARGS__)<br />
    #define LOG_GENERAL_ERROR(...)	   LOG_GENERAL(1, __VA_ARGS__)<br />
    #define LOG_GENERAL_WARNING(...)	  LOG_GENERAL(2, __VA_ARGS__)<br />
    #define LOG_GENERAL_NOTICE(...)	   LOG_GENERAL(3, __VA_ARGS__)<br />
    #define LOG_GENERAL_INFO(...)	   LOG_GENERAL(4, __VA_ARGS__)<br />
    #define LOG_GENERAL_DEBUG(...)	   LOG_GENERAL(5, __VA_ARGS__)<br />
    #define LOG_GRAPHICS_CRITICAL(...)	  LOG_GRAPHICS(0, __VA_ARGS__)<br />
    #define LOG_GRAPHICS_ERROR(...)	   LOG_GRAPHICS(1, __VA_ARGS__)<br />
    #define LOG_GRAPHICS_WARNING(...)	  LOG_GRAPHICS(2, __VA_ARGS__)<br />
    #define LOG_GRAPHICS_NOTICE(...)	  LOG_GRAPHICS(3, __VA_ARGS__)<br />
    #define LOG_GRAPHICS_INFO(...)	   LOG_GRAPHICS(4, __VA_ARGS__)<br />
    #define LOG_GRAPHICS_DEBUG(...)	   LOG_GRAPHICS(5, __VA_ARGS__)<br />
    #else<br />
    #define LOG_MESSAGE(domain, level, levelText, ...)<br />
    #define LOG_NETWORK(level, levelText, ...)  <br />
    #define LOG_GENERAL(level, levelText, ...)  <br />
    #define LOG_GRAPHICS(level, levelText, ...)  <br />
    #define LOG_NETWORK_CRITICAL(...)	<br />
    #define LOG_NETWORK_ERROR(...)	 <br />
    #define LOG_NETWORK_WARNING(...)	<br />
    #define LOG_NETWORK_NOTICE(...)	 <br />
    #define LOG_NETWORK_INFO(...)	 <br />
    #define LOG_NETWORK_DEBUG(...)	 <br />
    #define LOG_GENERAL_CRITICAL(...)	<br />
    #define LOG_GENERAL_ERROR(...)	 <br />
    #define LOG_GENERAL_WARNING(...)	<br />
    #define LOG_GENERAL_NOTICE(...)	 <br />
    #define LOG_GENERAL_INFO(...)	 <br />
    #define LOG_GENERAL_DEBUG(...)	 <br />
    #define LOG_GRAPHICS_CRITICAL(...)	<br />
    #define LOG_GRAPHICS_ERROR(...)	 <br />
    #define LOG_GRAPHICS_WARNING(...)	<br />
    #define LOG_GRAPHICS_NOTICE(...)	<br />
    #define LOG_GRAPHICS_INFO(...)	 <br />
    #define LOG_GRAPHICS_DEBUG(...)	 <br />
    #endif<br />
    <br />
    <br />
    ---<br />
    <br />
    <br />
    <br />
    #if DEBUG<br />
    <br />
    NSString *LOG_LEVEL_TEXT_FROM_INT(int level) {<br />
    	switch (level) {<br />
    		case 0:<br />
    			return @&quot;[CRITICAL]: &quot;;<br />
    			<br />
    		case 1:<br />
    			return @&quot;[ERROR]: &quot;;<br />
    			<br />
    		case 2:<br />
    			return @&quot;[WARNING]: &quot;;<br />
    			<br />
    		case 3:<br />
    			return @&quot;[NOTICE]: &quot;;<br />
    			<br />
    		case 4:<br />
    			return @&quot;[INFO]: &quot;;<br />
    			<br />
    		case 5:<br />
    			return @&quot;[DEBUG]: &quot;;<br />
    		<br />
    		default:<br />
    			return @&quot;[UNDEFINED]: &quot;;<br />
    	}<br />
    }<br />
    <br />
    #endif<br />
    




    Le gros avantage de cette version est que les macro de log fonctionnent que je sois dans une méthode ou dans une fonction.



    Maintenant je perd une chose vraiment intéressante de mes macros précédentes, je n'ai pas l'adresse de l'objet qui me parle.



    Je suis donc à  la recherche d'une méthode précompilo qui me permet de faire un "si le mot clef self est disponible dans le contexte, alors... sinon..."
  • AliGatorAliGator Membre, Modérateur
    septembre 2012 modifié #26
    'yoann' a écrit:


    Le gros avantage de cette version est que les macro de log fonctionnent que je sois dans une méthode ou dans une fonction.



    Maintenant je perd une chose vraiment intéressante de mes macros précédentes, je n'ai pas l'adresse de l'objet qui me parle.



    Je suis donc à  la recherche d'une méthode précompilo qui me permet de faire un "si le mot clef self est disponible dans le contexte, alors... sinon..."


    Facile :
    #define CODE_IS_IN_METHOD (__PRETTY_FUNCTION__[1] == &#39;[&#39;)
    
  • Je sens venir ma nouvelle petite habitude ... c'est vrai que les commentaires au bout d'un moment c'est plus de la mauvaise herbe verte qu'autre chose image/crazy.gif' class='bbc_emoticon' alt=' B) ' />
  • Puisqu'on parle de l'iPhone 5 en ce moment.. J'ai décidé de ne pas me précipiter et de rendre certaines fonctions utiles à  l'iPhone 5.

    Voici donc un simple define qui permet d'identifier l'iPhone 5, en attendant mieux de la part d'Apple..
    <br />
    [color=#6B6EC7][font=Menlo][size=2]<br />
    [b]#define DeviceIsPhone568H                   ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone \[/b][/size][/font][/color][color=#6B6EC7][font=Menlo][size=2]<br />
    [b]                                            &amp;&amp; CGRectGetHeight([[UIScreen mainScreen] bounds]) &gt;= [/b][color=#d83f82][b]568.[/b][/color][b])[/b][/size][/font][/color]<br />
    
  • muqaddarmuqaddar Administrateur
    Merci, oui ça sera utile.

    Je mettrai plutôt == 568 non ?



    Car si un jour on a un iPhone de 640 de haut, il faudra modifier cette macro. ;-)
  • Normalement il ne faut jamais faire de == sur des flottants. Il suffira de rajouter && < nouvelleHauteurDuProchainiPhone

    Mais à  mon avis on est tranquille un bon bout de temps image/tongue.png' class='bbc_emoticon' alt=':P' />
  • muqaddarmuqaddar Administrateur
    'ldesroziers' a écrit:


    Normalement il ne faut jamais faire de == sur des flottants.




    Je ne connaissais pas cette règle.
Connectez-vous ou Inscrivez-vous pour répondre.