Swift中为SKSpriteNode扩展实现Getter和Setter的问题
解决SKSpriteNode扩展中属性递归的问题
嘿,这个递归问题我太熟了!你写的代码之所以会无限循环,是因为你把HAKEK定义成了计算属性,但又在get和set里直接调用它自己——相当于每次获取或者设置值的时候,都在反复调用getter/setter,自然会栈溢出啦。而且Swift的类扩展默认不能直接添加存储属性,所以得用**关联对象(Associated Objects)**来实现类似存储属性的效果。
下面是修正后的代码:
import SpriteKit import ObjectiveC // 定义一个唯一的关联对象键,用地址作为标识 private var HAKEKKey: UInt8 = 0 extension SKSpriteNode { var HAKEK: Int { get { // 从关联对象中取值,未设置过则返回默认值0 return objc_getAssociatedObject(self, &HAKEKKey) as? Int ?? 0 } set { // 将新值绑定到当前SKSpriteNode实例 objc_setAssociatedObject(self, &HAKEKKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } }
关键细节解释:
- 我们需要一个唯一的
HAKEKKey作为关联对象的标识,这里用UInt8类型的变量就行,它的内存地址是唯一的,不会和其他关联对象冲突。 get方法里通过objc_getAssociatedObject取出绑定在当前实例上的值,用?? 0处理未初始化的情况。set方法里用objc_setAssociatedObject把新值和当前实例绑定,最后一个参数是内存管理策略,对于Int这种值类型,.OBJC_ASSOCIATION_RETAIN_NONATOMIC完全够用。
现在你就能正常使用这个属性了,不会再出现递归问题:
let mySprite = SKSpriteNode() mySprite.HAKEK = 123 print(mySprite.HAKEK) // 输出123
内容的提问来源于stack exchange,提问作者Harcker
相关产品推荐
相关产品推荐

