如何初始化相互依赖的属性 [英] How to initialize properties that depend on each other
问题描述
我希望图片移到底部.如果按按钮,图片应向下移动1.
我添加了图片和一个按钮:
var corX = 0
var corY = 0
var runter: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
var image = UIImage(named: "panzerBlau.jpg");
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40)); //
override func viewDidLoad() {
super.viewDidLoad()
panzer.image = image; //
self.view.addSubview(panzer); //
runter.frame = CGRectMake(100, 30, 10 , 10)
runter.backgroundColor = UIColor.redColor()
view.addSubview(runter)
runter.addTarget(self, action: "fahren", forControlEvents:UIControlEvents.TouchUpInside)
}
至少我在"fahren"函数中说过将图片向下移动1.
func fahren(){
corY += 1
panzer.frame = CGRectMake(corX, corY, 30, 40) //
self.view.addSubview(panzer);
}
所以我的问题是:这些corX和corY东西出现几个错误.没有它们,它会完美地工作,但比起一次性按钮更是如此.错误是:ViewController.Type没有名为corX的成员,ViewController.Type没有名为panzer的成员.
PS:我使用Xcode Beta5
这里是完整的代码,没有其他内容:
import UIKit
class ViewController: UIViewController {
var corX = 0
var corY = 0
var runter: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
var image = UIImage(named: "panzerBlau.jpg");
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40));
override func viewDidLoad() {
super.viewDidLoad()
panzer.image = image;
self.view.addSubview(panzer);
runter.frame = CGRectMake(100, 30, 10 , 10)
runter.backgroundColor = UIColor.redColor()
view.addSubview(runter)
runter.addTarget(self, action: "fahren", forControlEvents:UIControlEvents.TouchUpInside)
}
func fahren(){
corY += 100
panzer.frame = CGRectMake(corX, corY, 30, 40)
self.view.addSubview(panzer);
}
}
@MartinR在这里指出了主要问题:
var corX = 0
var corY = 0
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40))
问题在于,Swift默认初始化程序无法引用另一个属性的值,因为在初始化时,该属性尚不存在(因为实例本身尚不存在).基本上,在panzer
的默认初始值设定项中,您隐式地引用self.corX
和self.corY
-但没有self
,因为self
正是我们在创建过程中所需要的.
一种解决方法是使初始化程序变得懒惰:
class ViewController: UIViewController {
var corX : CGFloat = 0
var corY : CGFloat = 0
lazy var panzer : UIImageView = UIImageView(frame: CGRectMake(self.corX, self.corY, 30, 40))
// ...
}
这是合法的,因为panzer
直到后来被实际代码首次引用时才进行初始化.到那时,self
及其属性已经存在.
I want a picture to move to the bottom. If I press a button the pic should move down by 1.
I added the picture and a button:
var corX = 0
var corY = 0
var runter: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
var image = UIImage(named: "panzerBlau.jpg");
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40)); //
override func viewDidLoad() {
super.viewDidLoad()
panzer.image = image; //
self.view.addSubview(panzer); //
runter.frame = CGRectMake(100, 30, 10 , 10)
runter.backgroundColor = UIColor.redColor()
view.addSubview(runter)
runter.addTarget(self, action: "fahren", forControlEvents:UIControlEvents.TouchUpInside)
}
At least I said in function "fahren" to move the picture down by 1.
func fahren(){
corY += 1
panzer.frame = CGRectMake(corX, corY, 30, 40) //
self.view.addSubview(panzer);
}
So my problem is: I get several errors with these corX and corY thing. Without them it works perfectly but than its like a single-use button. The errors are: ViewController.Type does not have a member named corX and ViewController.Type does not have a member names panzer Where I get the errors I made // to show in which lines.
PS: I use Xcode Beta5
Here's the complete code without anything else:
import UIKit
class ViewController: UIViewController {
var corX = 0
var corY = 0
var runter: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
var image = UIImage(named: "panzerBlau.jpg");
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40));
override func viewDidLoad() {
super.viewDidLoad()
panzer.image = image;
self.view.addSubview(panzer);
runter.frame = CGRectMake(100, 30, 10 , 10)
runter.backgroundColor = UIColor.redColor()
view.addSubview(runter)
runter.addTarget(self, action: "fahren", forControlEvents:UIControlEvents.TouchUpInside)
}
func fahren(){
corY += 100
panzer.frame = CGRectMake(corX, corY, 30, 40)
self.view.addSubview(panzer);
}
}
@MartinR has pointed out the major issue here:
var corX = 0
var corY = 0
var panzer = UIImageView(frame: CGRectMake(corX, corY, 30, 40))
The problem is that a Swift default initializer cannot refer to the value of another property, because at the time of initialization, the property doesn't exist yet (because the instance itself doesn't exist yet). Basically, in panzer
's default initializer you are implicitly referring to self.corX
and self.corY
- but there is no self
because self
is exactly what we are in the middle of creating.
One workaround is to make the initializer lazy:
class ViewController: UIViewController {
var corX : CGFloat = 0
var corY : CGFloat = 0
lazy var panzer : UIImageView = UIImageView(frame: CGRectMake(self.corX, self.corY, 30, 40))
// ...
}
That's legal because panzer
doesn't get initialized until later, when it is first referred to by your actual code. By that time, self
and its properties exist.
这篇关于如何初始化相互依赖的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!