swift - 在 Swift 中使用 static let 实现的单例中为属性赋值

标签 swift singleton value-type reference-type

从阅读看来,在 Swift 中创建单例的最佳建议是使用 static let,如下所示:

struct GameManager {
  static let defaultManager = GameManager()
  var gameScore = 0
  var saveState = 0
  private init() {}
}

GameManager.defaultManager.gameScore = 1024 // Error
GameManager.defaultManager.saveState = 12 // Error
let score = GameManager.defaultManager.gameScore
let savedProgress = GameManager.defaultManager.saveState

由于 defaultManager 被声明为常量(使用“let”),因此当我尝试分配 gameScoresaveState 时出现错误>.

playground error cannot assign to property

我正在使用 Swift 2.0 (swiftlang-700.0.57.3 clang-700.0.72) 运行 Xcode 7.0 beta 6 (7A192o)。

如果我将 defaultManager 更改为变量(使用“var”)声明,它将不再被视为正确的单例吗?


如果我将 GameManager 更改为声明为类而不是结构,则代码将按预期工作。

class GameManager {
  static let defaultManager = GameManager()
  var gameScore = 0
  var saveState = 0
  private init() {}
}

GameManager.defaultManager.gameScore = 1024 // No error, why?
GameManager.defaultManager.saveState = 12 // No error, why?
let score = GameManager.defaultManager.gameScore // 1,024
let savedProgress = GameManager.defaultManager.saveState // 12

你能解释一下为什么引用类型类比值类型结构更适合实现单例吗?

最佳答案

你不能真正改变它,因为在你的结构上你有一个 let名为 defaultManager 的常量。正如您所知,结构是一种复制类型,而类是按引用传递的类型。如果你想将它用作结构,则必须替换 letvar反而。解决此问题的另一种方法是将结构更改为 class这样您就可以更改 defaultManager值,尽管它被声明为 let .

干杯

编辑:代码中的主要区别在于,当 class 中有一个常量时当你改变这个常量时,你实际上指的是它的地址而不是它的实际值。 struct 不会发生同样的情况。因为作为值类型,你不能像 class 那样通过引用调用。所以你被迫有一个不能改变的常量( let )值。更改letvar在你的struct里面看看奇迹发生

关于swift - 在 Swift 中使用 static let 实现的单例中为属性赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32487723/

相关文章:

swift - 从 Firebase 检索时实际未设置变量

iOS 本地通知 : app is not asking for permissions to notify the user

singleton - 对于带有参数的构造函数,goog.addSingletonGetter() 是否有变体?

ios - 初始化核心数据 ManagedObjectContext

c# - 为什么我的 INT 变量是通过引用传递的? C#

.net - ValueType 包装器的垃圾收集

swift - 将字符串分配给 uilabel swift 时出错

ios - 横向模式下的 UINavigationBar 高度未完全显示

Java - 是否有任何理由两次检查单例是否为空?

c# - 是否有使泛型推理变得不可能的值类型的解决方法?