我试图通过扩展向 SKSpriteNode 类添加属性,但运行失败。
这里我声明一个扩展:
extension SKSpriteNode {
var figureNumber:Int? {
get {
return self.figureNumber
}
set {
self.figureNumber = newValue
}
}}
在这里我创建了我的 Sprite :
let sprite = SKSpriteNode(imageNamed: "1.png")
sprite.position = CGPoint(x: 100, y: 100)
sprite.size = CGSize(width: 20, height: 20)
sprite.zPosition = 2
sprite.anchorPoint = CGPoint(x: 0.5, y: 0.5)
sprite.name = "small"
sprite.figureNumber = 1
addChild(sprite)
它失败并出现错误 SKSpriteNode.figureNumber.setter。 有什么想法有什么问题吗?
最佳答案
您正在从其自己的 setter 中设置计算属性,因此您将死于无限递归。
就目前情况而言,没有理由拥有您提供的 setter/getter — 如果您所做的只是获取和设置,那么只拥有声明的属性本身就可以了:
var figureNumber: Int?
如果这里实际发生的情况是您希望在该 setter/getter 中添加一些额外的逻辑,那么您实际需要的是选择这两个替代方案之一...
didSet
/willSet
如果您想对正在写入的属性执行一些副作用,请添加属性观察器。例如:
var figureNumber: Int? {
didSet {
texture = SKTexture(imageNamed: "\(figureNumber).png")
}
}
独立的属性(property)
在 Swift 中,属性的后备存储(您似乎试图访问的内容)不可访问。如果您的逻辑需要控制后备存储(例如,要使一个属性的值按需计算,缓存以供以后使用,并且可以在需要时清除其缓存),请使用计算属性和单独的私有(private)存储属性:
private var figureNumberStorage: Int?
var figureNumber: Int! {
get {
if figureNumberStorage == nil {
figureNumberStorage = generateFigureNumber()
}
return figureNumberStorage
}
set(newValue) {
figureNumberStorage = newValue
}
}
(这个例子做了可清除缓存的事情,并将其包装为一个 IUO,这样你就可以将它设置为 nil,而不必担心它在访问它时为零。并不是说你真的需要整个缓存业务一个整数...)
<小时/>至少,如果您正在实现类/结构,那么您可以这样做。。在扩展中,您无法添加存储的属性,因此您必须找到另一个位置来为计算属性放置后备存储。对于 SKNode
来说,userData
属性为您提供了一个方便的位置来存储与节点关联的其他内容:
let NumberKey = "number"
extension SKNode {
var number: Int? {
get {
return userData?.valueForKey(NumberKey) as? Int
}
set(newValue) {
if userData == nil {
userData = NSMutableDictionary()
}
userData?.setValue(newValue, forKey: NumberKey)
}
}
}
关于ios - 对 SKSpriteNode 进行扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33418731/