Je veux définir des méthodes min et max dans une classe Utils.
@interface Utils int min(int a, int b); int max(int a, int b); @end
Mais je ne veux pas avoir de parameters nommés. Ce serait une notation trop lourde. Je voulais utiliser la définition de style C. Mais alors [Utils min(a, b)]
comme un appel ne fonctionne pas. Quel est mon problème?
Merci d’avance pour votre aide
Etant donné que vous n’utilisez pas l’implémentation de l’objective-c dans OS X, il est possible que vous n’ayez pas access aux macros MIN et MAX prédéfinies.
Vous pouvez les définir vous-même comme
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b))
Il existe probablement un meilleur moyen de les définir, mais ceux-ci créeront les macros simples que vous utiliserez. Vous pouvez les append à n’importe quel fichier .h commun que vos classes partagent normalement.
Il est déjà défini comme une macro.
MIN(a, b) MAX(a, b)
Vous n’avez pas besoin de redéfinir ceux-ci.
La solution publiée par Brandon Bodnár pose un grave problème de sécurité (qui, au moment de la rédaction de cet article, est considérée comme une solution valide).
Problème décrit ici: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html Et la solution (valide & sécurisée) qui y est associée : http://gcc.gnu. org / onlinedocs / gcc-3.4.6 / gcc / Typeof.html
Vérifiez vous-même:
#include #define NAIVE_MAX(a,b) (a > b ? a : b) #define NAIVE_MIN(a,b) (a < b ? a : b) #if !defined MAX #define MAX(a,b) \ ({ __typeof__ (a) __a = (a); \ __typeof__ (b) __b = (b); \ __a > __b ? __a : __b; }) #endif #if !defined MIN #define MIN(a,b) \ ({ __typeof__ (a) __a = (a); \ __typeof__ (b) __b = (b); \ __a < __b ? __a : __b; }) #endif int main (int argc, const char * argv[]) { int a = 3; int b = 5; #pragma mark NON-FATAL CASES: printf("NAIVE_MAX(%d, %d) => %d\n", a, b, NAIVE_MAX(a, b)); printf("NAIVE_MIN(%d, %d) => %d\n", a, b, NAIVE_MIN(a, b)); printf("MAX(%d, %d) => %d\n", a, b, MAX(a, b)); printf("MIN(%d, %d) => %d\n", a, b, MIN(a, b)); printf("\nEverything fine so far...\n\n"); #pragma mark FATAL CASES: //cache: int _a = a; int _b = b; printf("NAIVE_MAX(%d++, %d++) => %d\n", _a, _b, NAIVE_MAX(a++, b++)); //reset: a = _a; b = _b; printf("NAIVE_MIN(%d++, %d++) => %d\n", _a, _b, NAIVE_MIN(a++, b++)); //reset: a = _a; b = _b; printf("NAIVE_MAX(++%d, ++%d) => %d\n", _a, _b, NAIVE_MAX(++a, ++b)); //reset: a = _a; b = _b; printf("NAIVE_MIN(++%d, ++%d) => %d\n", _a, _b, NAIVE_MIN(++a, ++b)); printf("\nOuch, this doesn't look right at all!\n\n"); #pragma mark NON-FATAL CASES: //reset: a = _a; b = _b; printf("MAX(%d++, %d++) => %d\n", _a, _b, MAX(a++, b++)); //reset: a = _a; b = _b; printf("MIN(%d++, %d++) => %d\n", _a, _b, MIN(a++, b++)); //reset: a = _a; b = _b; printf("MAX(++%d, ++%d) => %d\n", _a, _b, MAX(++a, ++b)); //reset: a = _a; b = _b; printf("MIN(++%d, ++%d) => %d\n", _a, _b, MIN(++a, ++b)); printf("\nAh, much better now.\n\n"); return 0; }
Journal de la console:
NAIVE_MAX(3, 5) => 5 NAIVE_MIN(3, 5) => 3 MAX(3, 5) => 5 MIN(3, 5) => 3 Everything fine so far... NAIVE_MAX(3++, 5++) => 6 NAIVE_MIN(3++, 5++) => 4 NAIVE_MAX(++3, ++5) => 7 NAIVE_MIN(++3, ++5) => 5 Ouch, this doesn't look right at all! MAX(3++, 5++) => 5 MIN(3++, 5++) => 3 MAX(++3, ++5) => 6 MIN(++3, ++5) => 4 Ah, much better now.
Donc, n’utilisez jamais l’implémentation naïve telle que décrite dans le code ci-dessus (et comme suggéré par Brandon Bodnár, désolé, mon pote;)) si vous voulez éviter les pires cas comme ceux-ci.
Ce n’est probablement pas une bonne idée pour cette application particulière, mais il est possible d’écrire des méthodes Objective-C avec des parameters «sans nom», ou plutôt avec des noms de longueur nulle:
+ min:(int)a :(int)b; ... [Utils min:a :b]
(Le sélecteur serait @selector(min::)
.)
Les méthodes de classe Objective-C utilisent des parameters nommés, point. C’est comme ça.
Pourquoi ne pas en faire une fonction globale et gratuite? Vous ne devriez pas avoir besoin d’un cours d’utilitaire pour ce genre de chose.
Si vous ne voulez pas encombrer l’espace de noms global, vous pouvez utiliser Objective-C ++ (renommer tous les fichiers .m en .mm) et le placer dans un espace de noms.
Dans un fichier modèle nommé “XXIntegerMath.h”, déposez cette …
#import static inline NSInteger imax(NSInteger a, NSInteger b) { return a > b ? a : b; } static inline NSInteger imin(NSInteger a, NSInteger b) { return a < b ? a : b; }
Ensuite, dans votre classe Objective-C ...
#import "XXIntegerMath.h" NSInteger minValue = imin(someValue, someOtherValue);
Il ne souffre pas des problèmes décrits par Regexident.