서로 의존하는 속성을 초기화하는 방법
사진이 아래로 이동하고 싶습니다. 버튼을 누르면 사진이 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)
}
적어도 나는 "화씨"함수에서 그림을 1만큼 아래로 이동하라고 말했다.
func fahren(){
corY += 1
panzer.frame = CGRectMake(corX, corY, 30, 40) //
self.view.addSubview(panzer);
}
그래서 내 문제는 다음과 같습니다. corX 및 corY에 대해 몇 가지 오류가 발생합니다. 그것들이 없으면 완벽하게 작동하지만 일회용 버튼과 같습니다. 오류는 다음과 같습니다. ViewController.Type에는 corX라는 멤버가없고 ViewController.Type에는 멤버 이름 panzer가 없습니다. 내가 만든 오류가 // 어떤 줄에 표시되는지 확인합니다.
추신 : 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그 속성이 존재합니다.
종속 자산은 다음과 같아야합니다.
lazy- 명시 적
: Type self.다른 속성에 액세스하는 데 사용
예:
let original = "foo"
// Good:
lazy var depend: String = self.original
// Error:
var noLazy: String = self.original // Error: Value of type '(NSObject) -> () -> URLData' has no member 'original'
lazy var noType = self.original // Error: Value of type '(NSObject) -> () -> URLData' has no member 'original'
lazy var noSelf: String = original // Error: Instance member 'original' cannot be used on type 'YourClass'
나는 질문의 제목을 언급하고 있습니다.
지연 및 계산 된 속성은 객체가 초기화 될 때까지 속성의 초기 값을 알 수 없는 경우를 처리하는 데 도움이됩니다 . 그러나 몇 가지 차이점이 있습니다. 차이점을 굵게 강조했습니다.
다른 변수가 초기화 된 후 변수를 초기화해야하는 lazy경우, 즉 단순히 지연을 추가하는 것이 중요하다면 (필요한 모든 속성이 이전에 초기화 됨) lazy를 사용하는 것이 올바른 방법입니다. 그것.
그러나 다른 변수를 기반으로 지속적 으로 변수를 변경 해야하는 경우 두 가지 방식으로 작동하는 계산 된 속성이 필요합니다 .
- 계산 된 속성이 설정 되면 관련 저장된 속성을 변수로 설정합니다.
- 저장된 속성이 설정 (또는 다시 재설정 )되면 계산 된 속성의 변경을 트리거합니다.
게으른 속성의 값을 변경하면 기반이 된 계층 속성에 영향을주지 않습니다. 여기를 참조 하십시오
당신은 일단 있다는 것 게으른 속성을 사용하는 좋은 예 firstName& lastName다음 유유히를 인스턴스화 할 fullName개체의 이름 성을 가능성 변경 절대은 FULLNAME 님이 만 수행 할 수 있습니다 일회성 만 ... 아니면 뭔가입니다 lazy속성에 의해 속성에 액세스하지 않을 때까지는 초기화되지 않으므로 클래스의 초기화로드 가 감소 합니다. 무거운 계산을 로드합니다 .
또한 다른 개발자에게 lazy의지 신호 를 사용합니다 . "먼저 다른 속성에 대해 읽어보고 그 속성이 무엇인지 이해 한 다음이 게으른 속성에 도달합니다 ...이 값은 속성을 기반으로하기 때문에 + 너무 일찍 접근하면 안되는 계산 ... "
당신이에 온도 설정하면 좋은 사례가 될 것이다 계산 된 속성으로 화씨 당신은 또한 당신의 원하는 섭씨 온도 값을 변경하는 ... 그리고 당신이 설정 한 경우 섭씨 다시 온도를 당신은 당신의 변경하려는 화씨 값입니다.
결과적으로 계산 된 속성은 추가 계산을 추가 할 것입니다. 계산이 매우 간단하고 너무 자주 호출되지 않으면 걱정할 필요가 없지만 너무 자주 호출되거나 CPU를 많이 소모하는 경우 더 좋을 수 있습니다. 다른 옵션을 생각하려면 ...
//
// ViewController.swift
//
// Created by Shivank Agarwal on 19/05/18.
// Copyright © 2018 Shivank Agarwal. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var corX = 0
var corY = 0
var runter: UIButton = UIButton()
var image = UIImage(named: "panzerBlau.jpg")
var panzer = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
panzer.image = image;
self.view.addSubview(panzer);
panzer.frame = CGRect(x: CGFloat(corX), y: CGFloat(corY), width: 30, height: 40)
runter.backgroundColor = UIColor.red
view.addSubview(runter)
view.addSubview(panzer)
runter.addTarget(self, action: Selector(("fahren")), for:UIControlEvents.touchUpInside)
}
private func fahren(){
corY += 100
}
private func updatePanzerFrame(){
panzer.frame = CGRect(x: CGFloat(corX), y: CGFloat(corY), width: 30, height: 40)
}
}
Note: Do not add panzer imageView every time when user tap only add it on viewDidLoad()
참고 URL : https://stackoverflow.com/questions/25854300/how-to-initialize-properties-that-depend-on-each-other
'Programing' 카테고리의 다른 글
| java : comp / env 란 무엇입니까? (0) | 2020.10.25 |
|---|---|
| Python 3-인코딩 / 디코딩 대 바이트 / Str (0) | 2020.10.25 |
| 메서드를 정의한 클래스 가져 오기 (0) | 2020.10.25 |
| "메모리 오류로 인해 종료 됨"을 디버깅 할 수 있습니까? (0) | 2020.10.25 |
| 요점의 마크 다운 파일에서 이미지에 대한 상대 링크를 만들 수 있습니까? (0) | 2020.10.24 |
