Pergunta

Quero definir um MIN e MAX Métodos em uma classe Utils.

@interface Utils

int min(int a, int b);
int max(int a, int b);

@end

Mas não quero ter parâmetros nomeados. Seria uma notação muito pesada. Eu queria usar a definição de estilo C. Mas então [Utils min(a, b)] Como uma chamada não funciona. Qual é o meu problema?

Agradecemos antecipadamente por qualquer ajuda

Foi útil?

Solução

Como você não está usando a implementação do OS X do Objective-C, pode não ter acesso às macros predefinidas MIN e Max.

Você pode defini -los você mesmo como

#define MIN(a,b)    ((a) < (b) ? (a) : (b))
#define MAX(a,b)    ((a) > (b) ? (a) : (b))

Provavelmente existe uma maneira melhor de defini -los, mas isso criará as macros simples para seu uso. Você pode adicioná -los a qualquer arquivo .h comum que suas classes compartilhem normalmente.

Outras dicas

Já está definido como uma macro.

MIN(a, b)

MAX(a, b)

Você não precisa redefinir esses.

Há um problema sério com a solução publicada por Brandon Bodnár (que na época em que este artigo foi escrito é marcado como uma solução válida).

Problema descrito aqui: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/min-and-max.htmlE a solução (válida e segura) para ele: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/typeof.html

Confira você mesmo:

#include <stdio.h>

#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;
}

Log do 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.

Então Nunca use a implementação ingênua Como visto no código acima (e como sugerido por Brandon Bodnár, desculpe amigo;)) se você quiser evitar os piores casos como esses.

Provavelmente não é uma boa ideia para este aplicativo em particular, mas é possível Escrever métodos Objective-C com parâmetros "sem nomes", ou melhor, com nomes de comprimento zero:

+ min:(int)a :(int)b;
...
[Utils min:a :b]

(O seletor seria @selector(min::).)

Métodos de classe Objective-C Use parâmetros nomeados, período. É assim que é.

Por que não torná -lo uma função global e gratuita? Você não deve precisar de uma aula de Utils para esse tipo de coisa.

Se você não quiser desordenar o espaço para nome global, pode usar o Objective-C ++ (renomeie todos os arquivos .m para .mm) e colocá-lo em um espaço para nome.

Em um arquivo de modelo chamado "xxintegererMath.h", solte isso ...

#import <Foundation/Foundation.h>

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;
}

Então, na sua classe Objective-C ...

#import "XXIntegerMath.h"
NSInteger minValue = imin(someValue, someOtherValue);

Não sofre com os problemas descritos pelo Regexident.

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