Swift单例或全局变量-还是其他?

时间:2018-11-05 12:04:20

标签: ios swift variables singleton global

我正在编写一个棋盘游戏。有两个屏幕和许多功能。我经常需要更改一些变量,例如“ money”或“ wood”。 我添加了“ didset”,以便可以更新显示金额的视图。

我看到两个选择。要么是全局变量,要么是

var money = 0 {didSet {NotificationCenter.default.post(name: NSNotification.Name(rawValue: "showMoney"), object: nil)}}

或单例

class resources {

static let shared = resources()

var money = 0 {didSet {NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ResourcenAnzeigen"), object: nil)}}

private init() {}

}

现在我读单例总是首选而不是全局变量。但是我不知道为什么。在我的示例中,两者似乎都做同样的事情。唯一的区别是我要么不得不写

money += 1

resources.shared.money += 1

第一个看起来更简单。

还有第三种更好的方法吗?我读到一个可以将所需的变量交给每个函数或视图控制器的方法-但是在我看来,这似乎是不必要的额外代码?

2 个答案:

答案 0 :(得分:2)

实际上,单例是全局变量的特例。 访问全局Singleton实例只是被遮蔽。 这有助于保持全局名称空间更整洁。

但是Singleton不应该用于全局访问。 在iOS中,Singleton用于唯一 资源,例如文件系统网络用户数据

我建议您在应用程序的根目录中创建一个实例,并将其注入到需要的位置。 这也使测试更加容易,并使代码保持干净。 在那里,您还可以使用观察者模式来避免使用全局NotificationCenter。

仅供参考:Communication Patterns

答案 1 :(得分:1)

Singleton是正确的方法。

出于这些目的使用全局变量而不是单例的主要问题是,如果您在某些其他实体中具有局部变量money,则编译器将无法隐式地识别出您所赚的钱在指。

因此,如果您决定将钱作为变量添加到其他位置,然后尝试在同一位置更新此 global money变量,最终将修改您的局部变量,而不会更新全局变量。

但是,当您使用单例来设置或获取此类属性时,可以避免这种情况。

var money = 0

class MyClass {

    var money = 0

    func doSomethingAndIncrementGlobalMoney() {
        money += 1
    }
}

print(money)   // Prints 0

let myObject = MyClass()
myObject.doSomethingAndIncrementGlobalMoney()

print(money)   // Prints 0, while the expectation was to increment the global 'money' by 1.

或者,您可以只使用类似的东西:

struct MyGlobalItems {
    static var money: Int = 0
}

// Using the variable:
MyGlobalItems.money += 1