我有一个应用程序,其中我想基于是否已经将等效对象保存到用户默认值来创建对象。如果检测到对象,我想在类init中检测到这一点并提前返回。这就是我想要做的事情:
init() {
/* There are two possibilities when creating a hero:
1. The hero is brand new and needs to be built from scratch
2. The hero is loaded from defaults */
// Check to see if there is existing game data:
if defaultExistsForGameData() {
// This means there is a hero to load and no need to create a new one
self = extractHeroFromDefaults() // This just loads from UserDefaults
print("Loading hero from defaults with name of: \(hero.heroName).")
return self
}
// These actions are for creating a brand new hero
let size = CGSize(width: 32, height: 32)
let heroTexture = SKTexture(imageNamed: "hero2.ico")
super.init(texture: heroTexture, color: .clear, size: size)
self.isUserInteractionEnabled = true
self.name = "hero"
self.zPosition = 50
}
控制台中有几个错误,self是不可变的等等。我想知道这是一个有效的模式,还是我应该采取完全不同的方法。
答案 0 :(得分:3)
在Swift中(与ObjC不同),init
无法返回与自身不同的对象。您实现此处尝试的常用方法是使用类工厂方法(如果您不希望其他对象能够直接调用它,则可选择将init
设为私有)。< / p>
例如,这些内容如下:
class func loadOrCreate() -> Hero {
if defaultExistsForGameData() {
// This means there is a hero to load and no need to create a new one
print("Loading hero from defaults with name of: \(hero.heroName).")
return extractHeroFromDefaults() // This just loads from UserDefaults
} else {
return Hero()
}
}
private init() {
let size = CGSize(width: 32, height: 32)
let heroTexture = SKTexture(imageNamed: "hero2.ico")
super.init(texture: heroTexture, color: .clear, size: size)
self.isUserInteractionEnabled = true
self.name = "hero"
self.zPosition = 50
}
更接近当前API的另一种方法是创建一个单独的(可能是私有的)指定的初始化程序,如下所示:
private init(name: String, zPosition: Int) {
let size = CGSize(width: 32, height: 32)
let heroTexture = SKTexture(imageNamed: "hero2.ico")
super.init(texture: heroTexture, color: .clear, size: size)
self.isUserInteractionEnabled = true
self.name = name
self.zPosition = zPosition
}
public convenience init() {
let name: String
let zPosition: Int
if defaultExistsForGameData() {
name = defaultName() // Read it out of user defaults
zPosition = defaultZPosition
} else {
name = "hero"
zPosition = 50
}
self.init(name: name, zPosition: zPosition)
}
这种方法的一个问题是它可能有点令人惊讶。如果您创建多个Hero
对象,那么应该发生的事情并不清楚。像loadOrCreate()
这样的东西非常清楚地表明存在外部影响。