2010-01-23 11 views
20

Voglio definire un metodo min e max in una classe Utils.Come si definisce un semplice metodo "min" in obj-c

@interface Utils 

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

@end 

Ma io non voglio avere parametri denominati. Sarebbe una notazione troppo pesante. Volevo usare la definizione in stile C. Ma poi [Utils min(a, b)] come una chiamata non funziona. Qual è il mio problema?

Grazie in anticipo per qualsiasi aiuto

+0

Ehi Fred, Se vuoi usare Object-C per farlo, usa la sintassi del linguaggio, e se non sei soddisfatto, usa puro C/C++, che farà quello che vuoi, nel modo in cui tu vuoi. Cheers, – vfn

+0

perché ci sono allora MIN e MAX macro e alcune piattaforme? –

+0

ATTENZIONE: la risposta attualmente accettata è considerata non sicura. (vedere il mio commento/risposta) – Regexident

risposta

18

Poiché non si sta utilizzando l'implementazione OS X dell'obiettivo-c, è possibile che non si abbia accesso alle macro predefinite MIN e MAX.

è possibile inserire questi stessi come

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

C'è probabilmente un modo migliore per definirli, ma questi saranno creare le semplici macro per il vostro uso. Puoi aggiungerli in qualsiasi file .h comune che le tue classi normalmente condividono.

+6

Questi devono essere usati con un granello di sale. MIN (i ++, j ++) per esempio non risulta come previsto. Vedi la mia risposta per i dettagli e la soluzione. – Regexident

1

metodi di classe Objective-C utilizzano parametri denominati, punto. È così e basta.

Perché non renderlo una funzione globale e gratuita? Non dovresti avere bisogno di una classe Utils per questo genere di cose.

Se non si desidera ingombrare il namespace globale, è possibile utilizzare Objective-C++ (rinominare tutti i file .m a .mm) e metterlo in uno spazio dei nomi.

59

È già definito come macro.

MIN(a, b) 

MAX(a, b) 

Non è necessario ridefinire questi.

+3

Stava per indicarlo. Perché scrivere il proprio quando è già implementato nel runtime obj-c. –

+1

è nel runtime obj-c o in quello MacOS. Sto usando gcc-objective-c e non ho potuto usare queste macro. –

+0

È definito in NSObjCRuntime.h, che molti non si trovano nei file di inclusione di gcc-obiettivo-c. –

6

Questo non è probabilmente una buona idea per questa particolare applicazione, ma è possibile scrivere metodi Objective-C con parametri “senza nome”, o meglio, con i nomi di lunghezza zero:

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

(Il selettore sarebbe @selector(min::).)

27

C'è un serio problema di sicurezza con la soluzione pubblicata da Brandon Bodnár (che al momento della stesura di questo documento è contrassegnata come una soluzione valida).

problema descritto qui: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html E la (& valida sicuro) soluzione ad esso: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

controllare voi stessi:

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

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. 

Così mai e poi mai usare l'ingenua implementazione come visto in t codice sopra (e come suggerito da Brandon Bodnár, amico spiacente;)) se vuoi evitare casi peggiori come questi.

0

In un file modello denominato "XXIntegerMath.h" rilasciare questo ...

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

Poi nella classe Objective-C ...

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

Non soffre dei problemi descritti da Regexident.