这远远超出了我的编程理解范围,所以非常感谢理解这个概念的任何帮助。
我所拥有的是一个图层类FloaterContainerLayer。
lazy var dotLayer : FloaterContainerLayer = {
let scrollLayer = FloaterContainerLayer()
scrollLayer.bounds = self.view.layer.bounds
scrollLayer.position = CGPoint(x: self.view.bounds.size.width/2, y: self.view.bounds.size.height/2)
scrollLayer.image = "dot"
scrollLayer.gravity = dotLayerGravity
return scrollLayer
}()
我总是有三个这个班级的实例。其中一个是dotLayer。
var dotLayerGravity: CGFloat {
get {
if let stored = userDefaults.objectForKey("dotLayerGravity") {
return CGFloat(stored as! NSNumber)
}
else {
return 10.0
}
}
set(value) {
userDefaults.setValue(value, forKey: "dotLayerGravity")
}
}
在其他地方,我有点图层的重力变量。
dotLayer.gravity
现在,此值可以随时更改。我在视图渲染方法中使用dotLayer.gravity = dotLayerGravity
,我每秒调用60次。
我想要完成的是:
我订的时候
dotLayer.gravity
并致电
dotLayerGravity
,
我希望它返回dotLayerGravity
。
只是将类中的重力变量设置为{{1}}不是一个选项,因为该类用于三个实例。
答案 0 :(得分:3)
使用CGFloat / Float / Double / Int,...作为指针在Swift中是不可能的,因为它们是值类型。一种可能的解决方案是创建一个简单的包装类,它将充当指针。
class CGFloatPointer : FloatLiteralConvertible {
var value : CGFloat = 0
required convenience init(floatLiteral value: Float) {
self.init()
self.value = CGFloat(value)
}
}
您可以使用FloatLiteralConvertible
之类的内容扩展此类,以便于使用。
var gravity:CGFloatPointer = 5.0
这比UnsafePointer
更容易维护。
一个小细节。从您的解释中可以看出,您将要从/向UserDefaults加载/保存很多。这很糟糕,因为它很慢。
对于你的代码,我会推荐一些介于全局变量和单例之间的东西,并抛出一些额外的魔法来规范读/写操作。
class DotLayerGravity {
private static var inMemory : CGFloat?
static var value: CGFloat {
get {
if let inMemory = inMemory {
return inMemory
} else {
let fetchedGravity = (NSUserDefaults.standardUserDefaults().objectForKey("dotLayerGravity") as? NSNumber) ?? 10
inMemory = CGFloat(fetchedGravity)
return inMemory!
}
}
set(value) {
NSUserDefaults.standardUserDefaults().setValue(value, forKey: "dotLayerGravity")
// setting this to nil will make it fetch from permanenent storage.
inMemory = nil
}
}
}
由于value
是static
属性,因此您可以在应用中的任何位置访问它。这根本不需要,但它确实只保证了这个值的一个实例。
inMemory
为private
,将保留NSUserDefaults
的值,直到写入操作完成。 private
为班级提供了一个更清晰的界面。
当您获得value
的值时,它会首先通过展开inMemory
来检查内存中是否有值,如果是nil
,它将在NSUserDefaults
上回退},当它也是nil
时,它将回退到默认值。
它会将获取的或默认值存储在inMemory
中并返回最终结果。
这确保了NSUserDefaults
的最小读取次数。
这不是线程安全的,但可以是。
重新阅读您的问题,向我明确表示每个实例都将gravity
存储在NSUserDefaults
中。在这种情况下,我会FloaterContainerLayer
通过设置和gravity
identifier
来String
对NSUserDefaults
充分负责。
class FloaterContainerLayer:CALayer {
var maxFloaters = 9
var image:String?
var velocity:CGFloat = 50.0
var identifier : String = "floaterContainerIdentifier"
private var inMemoryGravity : CGFloat?
var gravity: CGFloat {
get {
if let inMemory = inMemoryGravity {
return inMemory
} else {
let fetchedGravity = (NSUserDefaults.standardUserDefaults().objectForKey(identifier) as? NSNumber) ?? 10
inMemoryGravity = CGFloat(fetchedGravity)
return inMemoryGravity!
}
}
set(value) {
NSUserDefaults.standardUserDefaults().setValue(value, forKey: identifier)
// setting this to nil will make it fetch from permanenent storage.
inMemoryGravity = nil
}
}
}
class SomeViewController : UIViewController {
lazy var dotLayer : FloaterContainerLayer = {
let scrollLayer = FloaterContainerLayer()
scrollLayer.bounds = self.view.layer.bounds
scrollLayer.position = CGPoint(x: self.view.bounds.size.width/2, y: self.view.bounds.size.height/2)
scrollLayer.image = "dot"
scrollLayer.identifier = "dotLayerGravity"
return scrollLayer
}()
}
答案 1 :(得分:1)
仅支持功能而不是属性设置引用指针。这意味着您需要一个set方法
var testVariable: CGFloat = 100.0
class Test {
var testPtr: UnsafePointer<CGFloat>?
func setTestPtr(ptr: UnsafePointer<CGFloat>) {
self.testPtr = ptr
}
}
let t = Test()
t.setTestPtr(&testVariable)
testVariable = 110
let x = t.testPtr?.memory // 110