这似乎是一个基本问题,但我不知道答案。在我的应用程序中,您可以在每次游戏后赚取金币。这是我获取硬币和保存硬币的代码
let defaultCoins = UserDefaults()
var coinNumber = defaultCoins.integer(forKey: "coinSaved")
coinNumber = coinNumber + score
defaultCoins.set(coinNumber, forKey: "coinSaved")
我希望能够从不同的视图控制器访问coinNumber并能够使用它。所以也许做一个我可以在任何地方访问的变量= coinNumber。我有一个商店,并希望能够购买一个新的角色,当用户有1000个硬币,但目前无法做到这一点,因为我不知道如何从我的shopViewController访问coinNumber
答案 0 :(得分:1)
由于您要将数据保存到UserDefaults
,因此您似乎不需要在视图控制器之间传播数据 - 只需使用默认值作为您的真实来源&# 39;为了正确的价值。但是,只需将其保存为为所有iOS / OS X应用程序创建的标准对象,而不是将其保存到自定义UserDefaults对象:UserDefaults.standard
只要您需要,就可以按照上面的方式从中进行阅读。关于这种方法需要注意几点:
您可以使用键/值观察来检测其他控制器修改时对值的更改,但是您需要小心,因为如果您忘记正确删除观察者,KVO很容易崩溃。
您应该在其上调用synchronize
,这会强制您对磁盘进行更改。这将确保如果您的应用突然关闭,您已获得数据保护。
当您需要保存的数据少于10条时,UserDefaults非常适用,例如最高分或一组偏好(它是什么制作的)要做,但它对大型数据结构并不好。您应该查看CoreData或KeyedArchiver以获取更大的内容。
专业提示:而不是使用松散的字符串" coinSaved"一遍又一遍,在某处定义一个静态常量,或者使用字符串类型的枚举来预先定义所有值。然后,您将获得代码完成并避免错误。
所以,上面的代码看起来更像是:
在一个视图控制器中:
let defaultCoins = UserDefaults.standard
var coinNumber = defaultCoins.integer(forKey: "coinSaved")
coinNumber = coinNumber + score
defaultCoins.set(coinNumber, forKey: "coinSaved")
defaultCoins.synchronize()
然后,在另一个需要阅读它的控制器中:
let defaultCoins = UserDefaults.standard
let coinNumber = defaultCoins.integer(forKey: "coinSaved")
答案 1 :(得分:0)
您的主要问题是,无论何时尝试访问它,您都要创建一个新的UserDefaults
对象,您应该使用UserDefaults.standard
实例或创建一个具有特定标识符的实例。
如果您打算在多个视图控制器中使用它们,我还建议创建一个管理硬币的单例,这样可以节省您一遍又一遍地编写相同安全检查的时间(比如确保您不能这样做)花费比你多的硬币)
它看起来像这样:
class CoinManager {
static let shared = CoinManager()
private var _coins: UInt {
didSet {
UserDefaults.standard.set(_coins, forKey: "coinSaved")
}
}
var coins: UInt { return _coins }
private init() {
_coins = UInt(UserDefaults.standard.integer(forKey: "coinSaved"))
}
func spend(coins: UInt) -> Bool {
guard _coins > coins else { return false }
_coins -= coins
return true
}
func store(coins: UInt) -> UInt {
_coins += coins
return _coins
}
}
如您所见,其他对象只能读取coins
属性,但他们无法直接修改它,如果他们想要修改它,则必须使用spend
或{{ 1}}。 store
确保您无法支付比您更多的硬币。