从单例中获取可选字符串
Getting optional String from singleton
我创建了一个 class 带有一些 vars 和 lets。这些变量之一是 String
。我将它们存储在 UserDefaults
中。如果我想通过单例 class 访问此 class 的字符串,我将始终获得一个可选字符串。不知道为什么。
这里是对象的class:
import Foundation
import SpriteKit
class BallSkinsClass: NSObject, NSCoding {
let id: Int
var name: String
var isBuyed: Bool
let ID = "id"
let NAME = "name"
let ISBUYED = "isBuyed"
init(id: Int, name: String, isBuyed: Bool) {
self.id = id
self.name = name
self.isBuyed = isBuyed
}
required init?(coder aDecoder: NSCoder) {
self.id = aDecoder.decodeInteger(forKey: ID)
self.name = String(describing: aDecoder.decodeObject(forKey: NAME))
self.isBuyed = aDecoder.decodeBool(forKey: ISBUYED)
}
@objc func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: ID)
aCoder.encode(name, forKey: NAME)
aCoder.encode(isBuyed, forKey: ISBUYED)
}
}
为了声明皮肤、访问、保存和加载,我的 BallSkinsClass 中有这些函数:
import Foundation
import SpriteKit
import GameKit
class BallSkins {
static var sharedInstance = BallSkins()
private init() {
}
let BALLSKINS = "ballSkins"
var standard: BallSkinsClass! = BallSkinsClass(id: 0, name: "Standard", isBuyed: true)
var billiard: BallSkinsClass! = BallSkinsClass(id: 1, name: "Billard", isBuyed: false)
var emoji: BallSkinsClass! = BallSkinsClass(id: 2, name: "Emojis", isBuyed: false)
func archiveBallSkins(ballSkins:[BallSkinsClass]) -> NSData {
print("archiving Skins")
let archivedBallSkins = NSKeyedArchiver.archivedData(withRootObject: ballSkins as Array)
return archivedBallSkins as NSData
}
func saveBallSkins(ballSkins:[BallSkinsClass]) {
let archivedBallSkins = archiveBallSkins(ballSkins: ballSkins)
UserDefaults.standard.set(archivedBallSkins, forKey: BALLSKINS)
print("saving Skins")
}
func retrieveBallSkins() -> [BallSkinsClass]? {
print("retrieving Skins")
if let unarchivedBallSkins = UserDefaults.standard.object(forKey: BALLSKINS) as? NSData {
return NSKeyedUnarchiver.unarchiveObject(with: unarchivedBallSkins as Data) as? [BallSkinsClass]
}
return nil
}
func loadBallSkins() {
print("loading Skins")
let archivedBallSkins = retrieveBallSkins()
for ballSkin in archivedBallSkins! {
switch ballSkin.id {
case 0 :
standard.isBuyed = ballSkin.isBuyed
case 1:
billiard.isBuyed = ballSkin.isBuyed
case 2:
emoji.isBuyed = ballSkin.isBuyed
default:
standard.isBuyed = ballSkin.isBuyed
}
}
}
}
如果我想访问任何其他场景或视图中的皮肤名称,我调用:
ballSkins.sharedInstance.billiard.name
但这每次都是可选的!我不知道错误的原因或位置。
我想是
造成的
required init?(coder aDecoder: NSCoder) {
self.id = aDecoder.decodeInteger(forKey: ID)
self.name = String(describing: aDecoder.decodeObject(forKey: NAME))
self.isBuyed = aDecoder.decodeBool(forKey: ISBUYED)
}
第 3 行生成可选字符串,因为根据文档
func decodeObject() -> Any?
and String(describing: ...) 不会打开您的值。您必须自己解包 UserDefaults 中的所有值,如果不可能为 nil,则提供 defaultValue
我创建了一个 class 带有一些 vars 和 lets。这些变量之一是 String
。我将它们存储在 UserDefaults
中。如果我想通过单例 class 访问此 class 的字符串,我将始终获得一个可选字符串。不知道为什么。
这里是对象的class:
import Foundation
import SpriteKit
class BallSkinsClass: NSObject, NSCoding {
let id: Int
var name: String
var isBuyed: Bool
let ID = "id"
let NAME = "name"
let ISBUYED = "isBuyed"
init(id: Int, name: String, isBuyed: Bool) {
self.id = id
self.name = name
self.isBuyed = isBuyed
}
required init?(coder aDecoder: NSCoder) {
self.id = aDecoder.decodeInteger(forKey: ID)
self.name = String(describing: aDecoder.decodeObject(forKey: NAME))
self.isBuyed = aDecoder.decodeBool(forKey: ISBUYED)
}
@objc func encode(with aCoder: NSCoder) {
aCoder.encode(id, forKey: ID)
aCoder.encode(name, forKey: NAME)
aCoder.encode(isBuyed, forKey: ISBUYED)
}
}
为了声明皮肤、访问、保存和加载,我的 BallSkinsClass 中有这些函数:
import Foundation
import SpriteKit
import GameKit
class BallSkins {
static var sharedInstance = BallSkins()
private init() {
}
let BALLSKINS = "ballSkins"
var standard: BallSkinsClass! = BallSkinsClass(id: 0, name: "Standard", isBuyed: true)
var billiard: BallSkinsClass! = BallSkinsClass(id: 1, name: "Billard", isBuyed: false)
var emoji: BallSkinsClass! = BallSkinsClass(id: 2, name: "Emojis", isBuyed: false)
func archiveBallSkins(ballSkins:[BallSkinsClass]) -> NSData {
print("archiving Skins")
let archivedBallSkins = NSKeyedArchiver.archivedData(withRootObject: ballSkins as Array)
return archivedBallSkins as NSData
}
func saveBallSkins(ballSkins:[BallSkinsClass]) {
let archivedBallSkins = archiveBallSkins(ballSkins: ballSkins)
UserDefaults.standard.set(archivedBallSkins, forKey: BALLSKINS)
print("saving Skins")
}
func retrieveBallSkins() -> [BallSkinsClass]? {
print("retrieving Skins")
if let unarchivedBallSkins = UserDefaults.standard.object(forKey: BALLSKINS) as? NSData {
return NSKeyedUnarchiver.unarchiveObject(with: unarchivedBallSkins as Data) as? [BallSkinsClass]
}
return nil
}
func loadBallSkins() {
print("loading Skins")
let archivedBallSkins = retrieveBallSkins()
for ballSkin in archivedBallSkins! {
switch ballSkin.id {
case 0 :
standard.isBuyed = ballSkin.isBuyed
case 1:
billiard.isBuyed = ballSkin.isBuyed
case 2:
emoji.isBuyed = ballSkin.isBuyed
default:
standard.isBuyed = ballSkin.isBuyed
}
}
}
}
如果我想访问任何其他场景或视图中的皮肤名称,我调用:
ballSkins.sharedInstance.billiard.name
但这每次都是可选的!我不知道错误的原因或位置。
我想是
造成的required init?(coder aDecoder: NSCoder) {
self.id = aDecoder.decodeInteger(forKey: ID)
self.name = String(describing: aDecoder.decodeObject(forKey: NAME))
self.isBuyed = aDecoder.decodeBool(forKey: ISBUYED)
}
第 3 行生成可选字符串,因为根据文档
func decodeObject() -> Any?
and String(describing: ...) 不会打开您的值。您必须自己解包 UserDefaults 中的所有值,如果不可能为 nil,则提供 defaultValue