你如何在obj-c中定义一个简单的"min"方法

Fre*_*ack 21 c methods objective-c max min

我想在Utils类中定义min和max方法.

@interface Utils

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

@end
Run Code Online (Sandbox Code Playgroud)

但我不想要命名参数.这将是一个太沉重的表示法.我想使用C风格的定义.但随后[Utils min(a, b)]呼叫不起作用.我的问题是什么?

在此先感谢您的帮助

Mon*_*ong 62

它已被定义为宏.

MIN(a, b)

MAX(a, b)
Run Code Online (Sandbox Code Playgroud)

你不需要重新定义这些.

  • 即将指出这一点.为什么在obj-c运行时已经实现了它自己编写. (3认同)

Reg*_*ent 29

BrandonBodnár发布的解决方案存在严重的安全问题(截至撰写本文时,该解决方案已被标记为有效解决方案).

这里描述的问题:http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html 而(有效和安全的)解决它:HTTP://gcc.gnu.组织/ onlinedocs/GCC-3.4.6/GCC/Typeof.html

自己检查一下:

#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;
}
Run Code Online (Sandbox Code Playgroud)

控制台日志:

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.
Run Code Online (Sandbox Code Playgroud)

因此,永远不要使用上面代码中看到的天真实现(并且正如BrandonBodnár所建议的,抱歉伙伴;))如果你想避免像这样的最坏情况.


Bra*_*nar 18

由于您没有使用objective-c的OS X实现,因此您可能无法访问预定义的MIN和MAX宏.

您可以将自己定义为

#define MIN(a,b)    ((a) < (b) ? (a) : (b))
#define MAX(a,b)    ((a) > (b) ? (a) : (b))
Run Code Online (Sandbox Code Playgroud)

可能有更好的方法来定义它们,但这些将创建供您使用的简单宏.您可以将它们添加到您的类通常共享的任何常见.h文件中.

  • 这些将与一粒盐一起使用.例如,MIN(i ++,j ++)不会产生预期的结果.请参阅我的答案以获取详细信息和解 (6认同)

Kev*_*eid 6

对于这个特定的应用程序来说,这可能不是一个好主意,但可以使用"无名称"参数编写Objective-C方法,或者使用零长度名称编写:

+ min:(int)a :(int)b;
...
[Utils min:a :b]
Run Code Online (Sandbox Code Playgroud)

(选择器将是@selector(min::).)