Swift-细说枚举(Enum)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift-细说枚举(Enum)相关的知识,希望对你有一定的参考价值。

参考技术A

声明一个方向的枚举,包含四个枚举值: 东/西/南/北.

Swift 的枚举成员在被创建时本身就是完备的值,这些值的类型是已经明确定义好的 Direction 类型. 不会像 Objective-C 一样被赋予一个默认的整型值。在上面的 Direction 例子中,east、west 、north、south不会被隐式地赋值为 0,1,2 和 3。

Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为原始值),则该值的类型可以是:字符串、字符、任意的整数值或浮点类型。

Swift的枚举类型提供了一个叫原始值(RawValues)的实现,它为枚举项提供了一个默认值,这个默认值在编译期间就是确定的。

通过原值值获取的枚举项是可选类型的,所以需要用if let 做一下判断。

未指定枚举值类型

隐式原始值

隐式原始值下枚举项使用系统的分配值:

显式原始值

隐式 + 显式原始值

这里使用了属性观察者,Swift里面的枚举更像一个对象,因此可以很方便的使用属性观察者对枚举值进行监听。

在 Swift 中,还可以定义这样的枚举类型,它的每一个枚举项都有一个附加信息,来扩充这个枚举项的信息表示,这又叫做关联值。

一定要学会使用关联值,这一点很重要。具体的使用后面的第九节会细说

通常情况下枚举是很容易进行相等判断的。一旦为枚举增加了关联值,Swift就没法正确的比较了,需要自己对该枚举实现 == 运算符。

借助 Comparable 协议,来实现枚举的比较。

遵守 CaseIterable 协议的swift枚举是可以遍历的,通过allCases获取所有的枚举成员.

app里面的接口地址,如果都放一起,命名或者寻找都不方便,可以用枚举的嵌套来设计。可以分散在多个文件中,方便维护和管理。

用枚举来管理系统里面的常量是一个不错的选择。

枚举中不能使用存储属性,但是可以使用计算属性,计算属性的内容是在枚举值或者枚举关联值中得到的。

在这里,可以认为枚举是一个类,introduced是一个成员方法,AppleDeivce.iPhone 就是一个AppleDeivce的实例,case们是它的属性。introduced里面的switch self,其实就是遍历这个匿名属性的所有场景,如iPad,iPhone等,然后根据不同的场景返回不同的值。

可以做枚举的自定义构造方法。

系统的打印协议

让枚举遵守这个协议

枚举可以进行扩展。可以将枚举中的case与method/protocol分隔开,阅读者可以快速消化枚举的内容。

设计一个网络类下的错误信息的处理功能。

在项目中经常使用 UserDefaults 来存储一下简单的用户信息。但是对 Key 的维护不会很方便。而且会想不起来。用枚举+结构体就能很好的解决这个问题。

这么设计APP的存储模块,是不是更有层级感,更加方便使用呢?

递归枚举是拥有另一个枚举作为枚举成员关联值的枚举。当编译器操作递归枚举时必须插入间接寻址层。可以在声明枚举成员之前使用 indirect关键字来明确它是递归的。 也可以声明在整个枚举前,让所有的枚举成员都是递归的。

在 Swift 中使用 Objective-C 枚举

【中文标题】在 Swift 中使用 Objective-C 枚举【英文标题】:Using Objective-C Enum in Swift 【发布时间】:2017-03-31 20:50:34 【问题描述】:

我在 Xcode 8.2(构建目标 8.0)的 swift 2.3 代码中调用了一个 Objective-C 方法。它接受一个 NS_ENUM 作为参数:

typedef NS_ENUM(NSUInteger, MLCMultipleChoiceSlideSubtype) 
  MLCMultipleChoiceSlideSubtypeQA,
  MLCMultipleChoiceSlideSubtypeFillInTheBlank,
  MLCMultipleChoiceSlideSubtypeUnknown
;

包含此枚举和方法的 .h 文件位于我的 bridging-header.h 文件中。这是objc方法的签名:

+ (nullable instancetype)slideWithSubtype:(MLCMultipleChoiceSlideSubtype)subtype testSlide:(nonnull TestSlide *)slide distractorFinder:(nonnull MultipleChoiceDistractorFinder *)distractorFinder;

然后我从 Swift 2.3 中这样称呼它:

if let mcSlide = MultipleChoiceSlide(subtype: .QA, testSlide: slide, distractorFinder: distractorFinder) 
    return mcSlide

当我编译它以进行调试并运行它时,它工作正常。但是,当我尝试将其存档并编译发布时,我收到以下消息:

  ... LessonConvertToMultipleChoiceOperation.swift:55:64: Static member 'QA' cannot be used on instance of type 'MLCMultipleChoiceSlideSubtype'

我不知道为什么这只会在我归档构建或如何修复它时发生。


编辑:根据我在其他地方看到的类似问题的答案,我在我的方案中将存档构建配置从 Release 更改为 Debug,现在它存档了。然而,这似乎不是一件好事。通过这样做,存档会包含我的调试符号吗?

【问题讨论】:

这听起来像是你的系统中存在的东西,但在编译源中不正确。不过,我根本不是这方面的专家。 如果没有看到整个项目,这很难回答。寻找“调试”和“发布”配置之间的差异。也许需要的东西被包裹在#ifdef DEBUG 中?守卫? 【参考方案1】:

原来我需要这样调用方法:

if let mcSlide = MultipleChoiceSlide.init(subtype: .QA, testSlide: slide, distractorFinder: distractorFinder) 
   return mcSlide

虽然我不确定为什么添加 .init 会有所帮助。

Clue found here

【讨论】:

以上是关于Swift-细说枚举(Enum)的主要内容,如果未能解决你的问题,请参考以下文章

Swift之枚举enum的语法和功能

Swift 枚举enum

Swift枚举使用String值获取Int Enum的值

Swift之深入解析枚举enum的底层原理

Swift 学习笔记 enum 枚举类型

Swift Syntax 01 - 枚举类型