【问题标题】:How to store value globally?如何在全球范围内存储价值?
【发布时间】:2017-06-12 17:42:22
【问题描述】:

代码将存储 x1 和 y1 变量,但一旦 touchesEnded 函数开始,它们就会恢复到原来的 0.0 值。我希望这些值在 touchesBegan 函数结束后保留​​。如何存储这些值?

var x1: CGFloat = 0.0
var y1: CGFloat = 0.0
var x2: CGFloat = 0.0
var y2: CGFloat = 0.0

//touch initialized
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        var x1 = location.x
        var y1 = location.y
        print(x1,y1)
    }
}

//touch ends
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        print(x1,y1)
        let location2 = touch.location(in: self)
        let x2 = location2.x
        let y2 = location2.y
        let originX = min(x1,x2)
        let originY = min(y1,y2)
        let cornerX = max(x1,x2)
        let cornerY = max(y1,y2)
        let boxWidth = cornerX - originX
        let boxHeight = cornerY - originY

        let box = SKSpriteNode()
        box.size = CGSize(width: boxWidth, height: boxHeight)
        box.color = SKColor.black
        box.position = CGPoint(x:originX, y: originY)
        addChild(box)

        print(x1,y1,x2,y2)
    }
}

【问题讨论】:

  • 为什么不声明 2 个变量 CGPoints 而不是 4 个 CGFloats?
  • 顺便说一句,您应该更改您的问题标题,因为您并没有尝试将属性设置为 GLOBAL。您想使用其方法更改您的类属性
  • @Leo 从他的角度来看,他正试图使全球化,所以我认为标题是正确的。我认为他没有意识到变量可以具有本地、类或全局范围,并且他想要一个类属性而不是真正的全局变量。
  • 你没有看我对你其他问题的回答吗?它已经有类变量
  • 我建议使用单例模式,它将这些值存储在可以从项目中的任何位置访问的设置类中,并保证只有一个设置对象实例,因此只有一个设置对象实例其中的值在内存中。

标签: swift sprite-kit 2d 2d-games


【解决方案1】:

您在每个函数中重新声明它们。因此它们仍然是该功能的本地。像在顶部所做的那样在外面声明它们,然后在函数内部设置值。可能没有必要使用 self,但这是一个好主意,因为它可以让您知道您正在使用的变量来自闭包之外。

var x1: CGFloat = 0.0
var y1: CGFloat = 0.0
var x2: CGFloat = 0.0
var y2: CGFloat = 0.0

//touch initialized
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
let location = touch.location(in: self)
self.x1 = location.x
self.y1 = location.y
print(x1,y1)

    }
}

//touch ends
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?){
for touch in touches{

print(x1,y1)
let location2 = touch.location(in: self)
self.x2 = location2.x
self.y2 = location2.y
let originX = min(self.x1,self.x2)
let originY = min(self.y1,self.y2)
let cornerX = max(self.x1,self.x2)
let cornerY = max(self.y1,self.y2)
let boxWidth = cornerX - originX
let boxHeight = cornerY - originY

let box = SKSpriteNode()
box.size = CGSize(width: boxWidth, height: boxHeight)
box.color = SKColor.black
box.position = CGPoint(x:originX, y: originY)
addChild(box)

print(self.x1,self.y1,self.x2,self.y2)

【讨论】:

    【解决方案2】:

    将其更改为在函数内不包含 var。使用 var,您可以创建一个隐藏类/全局变量的局部变量:

    //touch initialized
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
      for touch in touches{
        let location = touch.location(in: self)
        x1 = location.x
        y1 = location.y
        print(x1,y1)
    
      }
    }
    

    【讨论】:

      【解决方案3】:

      这也让我绊倒了几次。

      Swift 3 静默(甚至没有警告)shadows 你的属性(或全局变量——我只是从方法名称中猜测它是一个类)和 touchesBegan() 方法的局部变量:

      在计算机编程中,变量阴影发生在变量 在特定范围内声明(决策块、方法或内部 class) 与在外部作用域中声明的变量同名。

      您可以删除 varlet 声明以使其工作:

      x1 = location.x
      y1 = location.y
      

      ..或者您可以使用self 明确限定属性以使其更清晰:

      self.x1 = location.x
      self.y1 = location.y
      

      似乎有一些关于这种隐式阴影行为的讨论,这让我认为它将来可能会改变:https://google.com/search?q=variable+shadow+site:swift.org

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-17
        • 1970-01-01
        • 2020-07-11
        • 2021-09-07
        • 1970-01-01
        • 1970-01-01
        • 2016-07-02
        • 1970-01-01
        相关资源
        最近更新 更多