2010-01-23 14 views
20

Tôi muốn xác định phương thức tối thiểu và tối đa trong một lớp Utils.Bạn định nghĩa phương thức "min" đơn giản như thế nào trong obj-c

@interface Utils 

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

@end 

Nhưng tôi không muốn có thông số được đặt tên. Nó sẽ là một ký hiệu quá nặng. Tôi muốn sử dụng định nghĩa kiểu C. Nhưng sau đó [Utils min(a, b)] khi cuộc gọi không hoạt động. Vấn đề của tôi là gì?

Cảm ơn trước vì bất kỳ trợ giúp nào

+0

Hey Fred, Nếu bạn muốn sử dụng Object-C để làm điều đó, vì vậy hãy sử dụng cú pháp ngôn ngữ, và nếu bạn không hài lòng với điều này, hãy sử dụng C/C++ tinh khiết sẽ thực hiện những gì bạn muốn. bạn muốn. Chúc mừng, – vfn

+0

tại sao có các macro MIN và MAX và một số nền tảng? –

+0

THẬN TRỌNG: Câu trả lời hiện được chấp nhận được coi là không an toàn. (xem bình luận/câu trả lời của tôi) – Regexident

Trả lời

18

Vì bạn không sử dụng OS X Thực hiện mục tiêu-c, bạn có thể không có quyền truy cập vào các macro MIN và MAX được xác định trước.

Bạn có thể xác định các chính mình như

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

Có thể là một cách tốt hơn để xác định họ, nhưng chúng sẽ tạo ra các macro đơn giản để sử dụng. Bạn có thể thêm chúng vào bất kỳ tệp .h chung nào mà các lớp của bạn thường chia sẻ.

+6

Chúng được sử dụng với một hạt muối. Ví dụ MIN (i ++, j ++) không cho kết quả mong đợi. Xem câu trả lời của tôi để biết chi tiết và giải pháp. – Regexident

1

Phương pháp lớp Objective-C sử dụng tham số có tên, dấu chấm. Nó là như vậy.

Tại sao không biến nó thành chức năng toàn cầu, miễn phí? Bạn không nên cần một lớp học Utils cho loại điều này.

Nếu bạn không muốn làm lộn xộn không gian tên chung, bạn có thể sử dụng Objective-C++ (đổi tên tất cả các tệp .m thành .mm) và đặt nó vào một không gian tên.

59

Nó đã được định nghĩa là macro.

MIN(a, b) 

MAX(a, b) 

Bạn không cần phải xác định lại những quảng cáo này.

+3

Đã chuẩn bị chỉ ra điều này. Tại sao viết của riêng bạn khi nó đã được thực hiện trong thời gian chạy obj-c. –

+1

là trong thời gian chạy obj-c hoặc trong hệ điều hành MacOS. Tôi đang sử dụng gcc-objective-c và tôi không thể sử dụng các macro này. –

+0

Nó được định nghĩa trong NSObjCRuntime.h, nhiều tệp không nằm trong tệp gcc-objective-c bao gồm tệp. –

6

Đây có lẽ không phải là một ý tưởng tốt cho các ứng dụng đặc biệt này, nhưng nó là thể để viết phương pháp Objective-C với các thông số “không tên”, hay đúng hơn là với những cái tên zero-length:

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

(Bộ chọn sẽ là @selector(min::).)

27

Có một vấn đề bảo mật nghiêm trọng với giải pháp được đăng bởi Brandon Bodnár (vào thời điểm viết bài này được đánh dấu là giải pháp hợp lệ).

Issue được mô tả ở đây: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html Và (có giá trị & an toàn) giải pháp cho nó: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

Kiểm tra nó ra cho mình:

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

điều khiển đăng nhập:

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. 

Vì vậy không bao giờ sử dụng triển khai ngây thơ như đã thấy trong t ông mã ở trên (và theo đề xuất của Brandon Bodnár, xin lỗi bạn thân;)) nếu bạn muốn tránh những trường hợp xấu nhất như thế này.

0

Trong tệp mẫu có tên "XXIntegerMath.h", hãy thả mục này ...

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

Sau đó, trong lớp Objective-C của bạn ...

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

Nó không bị ảnh hưởng từ những vấn đề được mô tả bởi Regexident.

Các vấn đề liên quan