在 App 中维护状态
利用枚举捕捉和跟踪 app 的状态。
概览
有效管理状态是 app 开发的一个重要部分;状态是用于跟踪 app 当下使用情况的数据位。由于枚举定义有限数量的状态,并可以将关联值与每个状态捆绑,因此您可以用枚举来为 app 的状态及其内部流程建模。
使用枚举捕捉状态
以一个需要用户登录帐户的 app 为例。首次打开该 app 时,用户是未知的,因此该 app 的状态可以称为 unregistered。在用户注册或登录帐户后,状态为 logged in。在闲置一定时间后,用户会话可能会过期,使 app 进入 session expired 状态。
您可以使用枚举来指定 app 所需的确切状态。这种方法定义一个 App
类,其嵌套的 State
枚举仅包含您需要的具体状态:
class App {
enum State {
case unregistered
case loggedIn(User)
case sessionExpired(User)
}
var state: State = .unregistered
// ...
}
在这个模型中,每个状态用一个具有匹配名称的 case 来表示。loggedIn
和 sessionExpired
case 都包含用户作为关联值,而 unregistered
case 不包含关联值。在更新 app 的状态时,不管具体转换为何,都只有一个变量 (state
) 需要修改。
不要将状态分散到多个变量
在为 app 的状态建模时,也可以组合使用多个不同的变量来存放状态和所需数据,但不建议这么做。
在这个模型中,app 定义了两个变量:一个是用于储存用户信息的可选 user
,另一个是名为 sessionExpired
的布尔值。用户没有登录时,user
变量为 nil
;用户登录后,该变量便具有值。sessionExpired
变量的初始值是 false
,在会话过期时设为 true
。三个状态通过两个变量的不同组合来捕捉。
由于几种原因,使用这种方法容易出错;它可能会导致错误,也更加难以推断您的代码:
-
对于状态的每次变化,您需要同时更新
user
和sessionExpired
。 -
如果 app 的未来变化需要增加一个状态,您需要在每个现有状态变化中更新一个额外的变量。
-
这两个变量还有一个未使用的组合;尽管该组合并没有对应的状态,但可以将
user
设为nil
并将sessionExpired
设为true
。