이 간단한 클래스를 사용하면 컴파일러 경고가 나타납니다.
x
자체 setter / getter 내 에서 수정 / 액세스 시도
내가 이것을 이렇게 사용할 때 :
var p: point = Point()
p.x = 12
EXC_BAD_ACCESS를 얻습니다. ivar을 명시 적으로 백업하지 않고 어떻게해야합니까?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
답변
세터와 게터는 다음에 적용됩니다 computed properties
. 이러한 속성에는 인스턴스에 스토리지가 없습니다. 게터의 값은 다른 인스턴스 속성에서 계산됩니다. 귀하의 경우 x
할당 할 필요 가 없습니다 .
명시 적으로 : “명백한 ivar을 지원하지 않고 어떻게해야합니까?” 할 수 없습니다- 계산 된 속성을 백업하기 위해 무언가 가 필요 합니다. 이 시도:
class Point {
private var _x: Int = 0 // _x -> backingX
var x: Int {
set { _x = 2 * newValue }
get { return _x / 2 }
}
}
특히 Swift REPL에서 :
15> var pt = Point()
pt: Point = {
_x = 0
}
16> pt.x = 10
17> pt
$R3: Point = {
_x = 20
}
18> pt.x
$R4: Int = 10
답변
스위프트의 세터 / 게터는 ObjC와 매우 다릅니다. 이 속성은 계산 된 속성이되므로 ObjC에서 와 같이 지원 변수 가 없습니다_x
.
아래 솔루션 코드에서는 아무것도 저장 xTimesTwo
하지 않고 단순히 결과를 계산 하는 것을 볼 수 있습니다 x
.
계산 된 속성에 대한 공식 문서를 참조하십시오 .
원하는 기능은 속성 관찰자 일 수도 있습니다 .
필요한 것은 :
var x: Int
var xTimesTwo: Int {
set {
x = newValue / 2
}
get {
return x * 2
}
}
setter / getter 내에서 다른 속성을 수정할 수 있습니다.
답변
속성 관찰기를 사용하여 설정 값을 사용자 정의 할 수 있습니다. 이렇게하려면 ‘set’대신 ‘didSet’을 사용하십시오.
class Point {
var x: Int {
didSet {
x = x * 2
}
}
...
게터에 관해서는 …
class Point {
var doubleX: Int {
get {
return x / 2
}
}
...
답변
GoZoner의 답변을 자세히 설명하려면 다음을 수행하십시오.
여기서 진짜 문제는 게터를 재귀 적으로 호출한다는 것입니다.
var x:Int
{
set
{
x = newValue * 2 // This isn't a problem
}
get {
return x / 2 // Here is your real issue, you are recursively calling
// your x property's getter
}
}
위의 코드 주석과 같이 x 속성의 getter를 무한대로 호출하면 EXC_BAD_ACCESS 코드를 얻을 때까지 계속 실행됩니다 (Xcode 놀이터 환경의 오른쪽 하단에서 스피너를 볼 수 있음).
Swift 문서 의 예제를 고려하십시오 .
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var width = 0.0, height = 0.0
}
struct AlternativeRect {
var origin = Point()
var size = Size()
var center: Point {
get {
let centerX = origin.x + (size.width / 2)
let centerY = origin.y + (size.height / 2)
return Point(x: centerX, y: centerY)
}
set {
origin.x = newValue.x - (size.width / 2)
origin.y = newValue.y - (size.height / 2)
}
}
}
중심 계산 속성이 변수 선언에서 어떻게 수정되거나 자신을 반환하지 않는지 확인하십시오.
답변
재정의 setter
하고 getter
신속한 변수를 위해 아래 주어진 코드를 사용하십시오.
var temX : Int?
var x: Int?{
set(newX){
temX = newX
}
get{
return temX
}
}
getter / setter가 재정의되는 동일한 변수에 액세스하려고하면 무한 루프가 발생하므로 변수 값을 임시 변수에 유지해야합니다.
이렇게 간단하게 setter를 호출 할 수 있습니다
x = 10
주어진 코드 줄 아래에서 Getter가 실행됩니다.
var newVar = x
답변
로 재귀 적으로 정의 x
하고 x
있습니다. 누군가가 당신에게 몇 살을 묻는 것처럼? 그리고 당신은 “나의 나이 두 배입니다”라고 대답합니다. 의미가 없습니다.
당신은 내가 두 번 존의 연령이나 다른 변수입니다 말을해야 하지만 자신.
계산 된 변수는 항상 다른 변수에 의존합니다.
엄지 손가락의 규칙은 getter 내 에서 속성 자체에 절대 액세스 하지 않습니다 . 왜냐하면 다른 트리거 될 것이고 다른 트리거 될 것이다. . . 인쇄조차하지 마십시오. 인쇄는 인쇄하기 전에 값을 ‘얻어야’하기 때문에 필요합니다!get
get
struct Person{
var name: String{
get{
print(name) // DON'T do this!!!!
return "as"
}
set{
}
}
}
let p1 = Person()
따라서 다음과 같은 경고가 나타납니다.
자체 getter 내에서 ‘name’에 액세스하려고합니다.
오류는 다음과 같이 모호합니다.
대안으로 사용하고 싶을 수도 있습니다 didSet
. 함께 didSet
하기 전에 설정되고 단지로 설정되었다 값에 보류를 얻을 것이다. 자세한 내용은 이 답변을 참조하십시오 .
답변
업데이트 : Swift 4
아래 클래스에서 setter와 getter가 변수에 적용됩니다. sideLength
class Triangle: {
var sideLength: Double = 0.0
init(sideLength: Double, name: String) { //initializer method
self.sideLength = sideLength
super.init(name: name)
numberOfSides = 3
}
var perimeter: Double {
get { // getter
return 3.0 * sideLength
}
set(newValue) { //setter
sideLength = newValue / 4.0
}
}
객체 생성
var triangle = Triangle(sideLength: 3.9, name: "a triangle")
얻는 사람
print(triangle.perimeter) // invoking getter
세터
triangle.perimeter = 9.9 // invoking setter