【问题标题】:Correct way to declare property whose type is an enum value声明类型为枚举值的属性的正确方法
【发布时间】:2014-06-17 12:52:54
【问题描述】:

我希望我的班级有一个只能从枚举中分配值的属性,但我无法完全理解语法。这是我的头文件:

NS_ENUM(NSInteger, SPSSearchResultsOrder) {
  SPSSearchResultsOrderAlphabetical,
  SPSSearchResultsOrderPrice
};

@interface SPSSearchQuery : NSObject

@property (readonly, nonatomic) enum SPSSearchResultsorder searchResultsOrder;

// etc.

@end

Xcode 建议我将 enum 关键字添加到我的属性声明中以获取要编译的代码,这就是为什么我认为这是不对的。

是否应该将属性键入为NSInteger,因为那是枚举的类型?在这种情况下,我如何强制该属性只能分配枚举值之一?

如果我是用 Java 编写的,我会这样做:

public enum SearchResultsOrder {
  SearchResultsOrderAlphabetical,
  SearchResultsOrderPrice;
}

public class SearchQuery
  private SearchResultsOrder searchResultsOrder;

  public SearchResultsOrder getSearchResultsOrder() {
    return this.searchResultsOrder;
  }
}

——正如你所见,这里编译器能够强制枚举和成员变量类型之间的关系。什么是 Objective-C 等价物?

提前致谢。

【问题讨论】:

  • 如果你在NS_ENUM前面加上typedef,那么你可以在没有enum关键字的情况下将你的枚举类型称为SPSSearchResults

标签: objective-c


【解决方案1】:

您正在朝着正确的方向前进。您应该 typedef 枚举以便将它们用作类型:

typedef NS_ENUM(NSInteger, SPSSearchResultsOrder) {
    SPSSearchResultsOrderAlphabetical,
    SPSSearchResultsOrderPrice
};

@interface SPSSearchQuery : NSObject

@property (nonatomic, readonly, assign) SPSSearchResultsorder searchResultsOrder;

@end

此外,由于您的属性不是对象而是类型值(在您的情况下为NSInteger),您应该使用assign 关键字。此关键字选择退出为此属性生成的 ARC 内存管理 setter/getter。

NS_ENUM 宏实际上是在 Cocoa 中声明枚举的一种首选方式。使用这种方法,您将在 Xcode 中收到 typecheckingcode completion。如果您查看 Apple 的框架,您会发现它无处不在,而不是普通的枚举。尊重平台的编码风格! :)

【讨论】:

  • 是的; assign 属性是这里的关键!
  • 这行得通,但有趣的是它仍然没有将searchResultsOrder 的值限制为枚举中的常量之一。例如,我可以将 3 分配给支持该属性的实例变量。不过我可以忍受,因为作业只发生在我班级的初始化程序中。
【解决方案2】:

如果您使用NS_ENUM 定义枚举,我认为应该是NSInteger

但是我从不使用NS_ENUM,而是更喜欢普通的 C 语法,它更简单,意味着可以使用正确的类型:

enum SPSSearchResultsOrder {
  SPSSearchResultsOrderAlphabetical,
  SPSSearchResultsOrderPrice
};

...

@property (readonly, nonatomic) SPSSearchResultsOrder searchResultsOrder;

(请注意,您的代码中有 SPSSearchResultsorder)。

【讨论】:

  • 很有趣,谢谢。我使用了NS_ENUM,因为这似乎是当今做事的首选方式:nshipster.com/ns_enum-ns_options
  • @JohnTopley 是的,也许。我猜我从来没有遇到过它旨在解决的问题......
  • 使用 NS_ENUM/OPTIONS 可以让 Swift 编译器正确地将你的枚举转换为 Swift 枚举。
  • @Lance 另一个使用它的原因 ;-)
  • @Lance 知道这很有趣,但这段代码不会升级到 Swift。
猜你喜欢
  • 1970-01-01
  • 2022-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多