如何创建全局变量?

151

我有一个全局变量需要在多个视图控制器之间共享。

在 Objective-C 中,我可以定义一个静态变量,但我找不到在 Swift 中定义全局变量的方法。

您知道如何做吗?


如何在Swift中创建全局变量 - Steve Rosenberg
可能是如何在Swift中创建全局变量?的重复问题。 - Kode
你可以在类的外部定义变量或结构体,然后在整个应用程序中访问该变量。 - Chandni
4个回答

247

从官方的Swift编程指南

全局变量是在任何函数、方法、闭包或类型上下文之外定义的变量。全局常量和变量总是懒计算的。

你可以在任何文件中定义全局变量,并且可以在当前module中的任何地方访问它。 因此,你可以在文件的某个位置定义它,在任何作用域之外。不需要static,所有全局变量都是懒计算的。

 var yourVariable = "someString"

您可以从当前模块的任何地方访问此内容。

但是,您应该避免使用此内容,因为全局变量不利于应用程序状态,也是错误的主要原因。

正如此答案所示,在Swift中,您可以将它们封装在struct中并可以随处访问。您还可以在Swift中定义静态变量或常量。将其封装在struct中。

struct MyVariables {
    static var yourVariable = "someString"
}

您可以在任何类或任何地方使用此变量。

let string = MyVariables.yourVariable
println("Global variable:\(string)")

//Changing value of it
MyVariables.yourVariable = "anotherString"

4
你的结构体被称为MyVariables,因此MyViewState看起来像是从https://dev59.com/02Af5IYBdhLWcg3wQQq4#24868789复制/粘贴出现错误 :) - Martin R
11
如果您从其他答案中复制代码,则应明确说明(并提供指向原始答案的链接)。请参阅 http://stackoverflow.com/help/referencing。 - Martin R
2
明白了,谢谢!但是全局变量和封装在结构体中有什么区别吗? - czzhengkw
@郑克文,因此,在封装变量时,您可以通过 struct 控制所有变量的可见性,并且如果适当,还可以将它们绑定到不同的逻辑单元中。例如应用程序的音频常量和通用常量。 - codester
5
“MyVariables” 不会被视为全局变量吗?如果我们将其声明为全局结构体或变量,有什么区别? - Satyam
显示剩余8条评论

16

通过使用 private 关键字,可以对定义在任何方法或闭包之外的全局变量进行范围限制。

import UIKit

// MARK: Local Constants

private let changeSegueId = "MasterToChange"
private let bookSegueId   = "MasterToBook"

36
常量("let")不是变量。 - Mike Taverne
2
@MikeTaverne,你是对的,但你可以将其介绍为“var”,那么这个答案就没问题了。https://swifttipsnet.wordpress.com/2016/09/11/swift-global-variables-yes-way/ - Milad Faridnia

7

如果你想在所有的类中使用它,你可以使用:

public var yourVariable = "something"

如果您只想在一个类中使用,可以使用以下代码:

var yourVariable = "something"

-3

如果你实际上不想要一个全局变量,而是想保存即使应用关闭时仍然存在的值,可以这样做:

如果你实际上不想在视图控制器之间传递数据,而只是想存储一个全局变量,可以这样做:

这篇文章很好地解释了如何在Swift 5中实现这一点: https://www.hackingwithswift.com/example-code/system/how-to-save-user-settings-using-userdefaults

总结:

设置一个值:

let defaults = UserDefaults.standard
defaults.set("value", forKey: "key")

获取字符串值的方法:
let key = defaults.object(forKey: "StringKey") as? [String] ?? [String]()

获取整数值:

let key = defaults.integer(forKey: "IntegerKey")

离题了,这不是OP所问的。 - Eric Aya
2
另外,一个友好的提示:仅仅因为你需要在另一个视图控制器中使用该值,就使用UserDefaults保存值是非常错误的。有适当的方法可以传递该值,而无需将其写入本地存储。 - Eric Aya
当我在搜索如何保存数据,即使应用程序关闭也可以持久存在并且可以从所有视图控制器访问时,大多数我使用的搜索引擎都会出现这个SO问题。因此,我认为我的答案对于其他处于与我相同情况的人也会有用。 - Jeffrey Kozik
@EricAya 我同意如果你只是想在视图控制器之间传递数据,那么将数据写入本地存储是错误的。然而,一些查找如何执行此操作的人实际上可能并不想在视图控制器之间传递数据,他们可能需要更持久的数据,例如已登录到其应用程序的用户的标识符。这就是我发布此答案的原因。 - Jeffrey Kozik
这可能对那些试图解决与我类似问题的人有所帮助,但我理解你的观点。 - Jeffrey Kozik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接