Làm cách nào để xác định và sử dụng ENUM trong Objective-C?


180

Tôi đã khai báo một enum trong tệp thực hiện của mình như được hiển thị bên dưới và đã khai báo một biến loại đó trong giao diện của tôi là PlayerState thePlayerState; và sử dụng biến trong các phương thức của tôi. Nhưng tôi nhận được lỗi nói rằng nó không được công bố. Làm cách nào để khai báo chính xác và sử dụng biến kiểu PlayerState trong các phương thức của tôi?:

Trong tệp .m

@implementation View1Controller

    typedef enum playerStateTypes
        {
            PLAYER_OFF,
            PLAYER_PLAYING,
            PLAYER_PAUSED
        } PlayerState;

trong tệp .h:

@interface View1Controller : UIViewController {

    PlayerState thePlayerState;

trong một số phương thức trong tệp .m:

-(void)doSomethin{

thePlayerState = PLAYER_OFF;

}

2
Bây giờ loại enum làPlayerState. PlayerStateTypes trở thành gì?
dùng4951

3
Để biết thông tin về NS_ENUM và cú pháp hiện đại mới nhất của nó, hãy xem bài đăng NS_ENUM & NS_OPTIONS của Mattt Thompson.
Basil Bourque

Câu trả lời:


109

Bạn typedefcần phải ở trong tệp tiêu đề (hoặc một số tệp khác phù #importhợp với tiêu đề của bạn), vì nếu không trình biên dịch sẽ không biết kích thước để tạo ra PlayerStatengà. Ngoài ra, nó có vẻ ổn với tôi.


Tùy chọn để đặt nó trong một tệp riêng biệt có vẻ đúng trong trường hợp của tôi. Tôi không biết liệu đây có phải là một cách tiếp cận tốt hay không, nhưng tôi cần sử dụng cùng một enum trong hai ViewControllers khác nhau (bản thân và nó là đại biểu / nguồn dữ liệu). Nhập tiêu đề của đại biểu / nguồn dữ liệu dẫn đến một lỗi và dường như quá nhiều cho một nhu cầu đơn giản. Vì vậy, tôi đã tạo một tệp .h mới với enum được khai báo và nhập nó trên cả tệp viewControllers.h. Làm việc như người ở.
Leandro Alves

7
Nên khuyến nghị sử dụng macro NS_ENUM - vì đây là cách thực hành tốt nhất
khebbie

1
Bạn phải khai báo NS_ENUMenum bằng Objective-C nếu bạn muốn enum của bạn có sẵn trong mã Swift.
smileyborg

@DaveDeLong, Điều này có còn hiệu lực trong năm 2015 không? Tôi có typedefkhai báo trong .mtệp và nó biên dịch và chạy tốt.
Iulian Onofrei

@IulianOnofrei nó sẽ đi vào tệp .h nếu bạn cần sử dụng enum trong các tệp khác. Nếu bạn chỉ cần nó trong một tệp, đặt nó vào tệp .m luôn hoàn toàn ổn.
Dave DeLong

206

Apple cung cấp một macro để giúp cung cấp khả năng tương thích mã tốt hơn, bao gồm Swift. Sử dụng macro trông như thế này.

typedef NS_ENUM(NSInteger, PlayerStateType) {
  PlayerStateOff,
  PlayerStatePlaying,
  PlayerStatePaused
};

Tài liệu ở đây


Obj C Enums có thể có các biến thành viên như trong Java không? Nếu vậy thì thế nào?
thợ đồng hồ

Vậy giải pháp thứ hai có tốt hơn?
Iulian Onofrei

3
Giải pháp thứ hai là tốt hơn (sử dụng NS_ENUM), vì nó hiện đại hơn và hiện được yêu cầu trong Objective-C nếu bạn muốn enum của mình có sẵn trong mã Swift.
smileyborg

Cập nhật để hiển thị các giải pháp thứ hai trong thực tế là tốt hơn.
rebelzach

Ở dạng chuẩn của Apple, tên loại được lặp lại cho mỗi giá trị enum.
ThomasW

29

Trong .h:

typedef enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
} PlayerState;

1
Bạn có thể tìm thấy một câu trả lời như thế này trong các câu hỏi SO khác, nhưng khi tôi đang xem xét các enum, câu hỏi này xuất hiện đầu tiên, vì vậy tôi cũng đã thêm câu trả lời ở đây.
Ben Flynn

19

Với các dự án hiện tại bạn có thể muốn sử dụng NS_ENUM()hoặc NS_OPTIONS()macro.

typedef NS_ENUM(NSUInteger, PlayerState) {
        PLAYER_OFF,
        PLAYER_PLAYING,
        PLAYER_PAUSED
    };

2
... Và quan trọng hơn bây giờ, bạn phải khai báo NS_ENUMenum bằng Objective-C nếu bạn muốn enum của mình có sẵn trong mã Swift.
smileyborg

16

Đây là cách Apple làm điều đó cho các lớp như NSString:

Trong tệp tiêu đề:

enum {
    PlayerStateOff,
    PlayerStatePlaying,
    PlayerStatePaused
};

typedef NSInteger PlayerState;

Tham khảo Nguyên tắc mã hóa tại http://developer.apple.com/


3
Điều này không thực sự giúp OP. Mặc dù về mặt kỹ thuật, nó không cho họ biết cách tạo ra một enum có thể tái sử dụng
RyanR

24
Liên kết đến developer.apple.com không thực sự hữu ích. Có một số nơi khác mà bạn muốn trích dẫn thay thế?
Brett

Sao chép / dán tài liệu đã được cung cấp, liên kết là trang chính thực sự không giúp ích gì cho người khác ...
Onder OZCAN

3
Điều này hiện đã lỗi thời, hãy xem trang này developer.apple.com/l
Library / ios / releasenotes / OcjectiveC / Kẻ

8

Tôi khuyên bạn nên sử dụng NS_OPTIONS hoặc NS_ENUM. Bạn có thể đọc thêm về nó ở đây: http://nshipster.com/ns_enum-ns_options/

Đây là một ví dụ từ mã của riêng tôi bằng NS_OPTIONS, tôi có một tiện ích đặt một lớp con (CALayer) trên lớp của UIView để tạo đường viền.

Các h. tập tin:

typedef NS_OPTIONS(NSUInteger, BSTCMBorder) {
    BSTCMBOrderNoBorder     = 0,
    BSTCMBorderTop          = 1 << 0,
    BSTCMBorderRight        = 1 << 1,
    BSTCMBorderBottom       = 1 << 2,
    BSTCMBOrderLeft         = 1 << 3
};

@interface BSTCMBorderUtility : NSObject

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color;

@end

Tệp .m:

@implementation BSTCMBorderUtility

+ (void)setBorderOnView:(UIView *)view
                 border:(BSTCMBorder)border
                  width:(CGFloat)width
                  color:(UIColor *)color
{

    // Make a left border on the view
    if (border & BSTCMBOrderLeft) {

    }

    // Make a right border on the view
    if (border & BSTCMBorderRight) {

    }

    // Etc

}

@end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.