gpt4 book ai didi

ios - 使对象变量成为指向另一个变量的指针

转载 作者:搜寻专家 更新时间:2023-11-01 06:19:40 25 4
gpt4 key购买 nike

这远远超出了我的编程理解范围,因此非常感谢任何帮助理解这个概念的人。

我有一个层类,FloaterContainerLayer。

class FloaterContainerLayer:CALayer {
var gravity:CGFloat = 5.0
var maxFloaters = 9
var image:String?
var velocity:CGFloat = 50.0
}

我一直都有这个类的三个实例。其中之一是 dotLayer。

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
}()

在其他地方,我有一个点层的重力变量。

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")
}
}

现在,这个值可以随时更改。我在每秒调用 60 次的 View 渲染方法中使用 dotLayer.gravity

我想完成的是:

当我设置dotLayer.gravity = dotLayerGravity

然后打电话dotLayer.gravity,

我希望它返回 dotLayerGravity

仅将类中的重力变量设置为 dotLayerGravity 不是一个选项,因为该类用于三个实例。

我试过了,但是不行。 enter image description here

最佳答案

使用 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 属性,它可以在您的应用程序的任何地方访问。这根本不需要,但它确实保证只有一个该值的实例。

inMemoryprivate 并且将保存 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
}()
}

关于ios - 使对象变量成为指向另一个变量的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36386897/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com