programing

부동산 게터 및 세터

sourcejob 2023. 4. 29. 09:14
반응형

부동산 게터 및 세터

이 간단한 클래스로 컴파일러 경고를 받습니다.

수정입니다.x자신이 정한 범위 내에서

이렇게 사용하면 다음과 같이 됩니다.

var p: point = Point()
p.x = 12

저는 EXC_B를 받습니다.AD_ACCESS.명시적인 지원 ivar 없이 어떻게 할 수 있습니까?

class Point {

    var x: Int {
        set {
            x = newValue * 2 //Error
        }
        get {
            return x / 2 //Error
        }
    }
    // ...
}

는 에 적용됩니다.computed properties이러한 속성에는 인스턴스에 저장소가 없습니다. getter의 값은 다른 인스턴스 속성에서 계산됩니다. 의경우는, 없니다가 .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

속성 관찰자를 사용하여 설정 값을 사용자 지정할 수 있습니다.이렇게 하려면 'set' 대신 'didSet'을 사용합니다.

class Point {

var x: Int {
    didSet {
        x = x * 2
    }
}
...

기억나는 것은...

class Point {

var doubleX: Int {
    get {
        return x / 2
    }
}
...

Swift의 세터/게터는 ObjC와 상당히 다릅니다.속성이 계산된 속성이 됩니다. 즉, 다음과 같은 백업 변수가 없습니다._xObjC에서 그랬던 것처럼.

아래 솔루션 코드에서 다음을 확인할 수 있습니다.xTimesTwo아무것도 저장하지 않고 단순히 결과를 계산합니다.x.

계산된 속성에 대한 공식 문서를 참조하십시오.

원하는 기능은 속성 관찰자일 수도 있습니다.

필요한 것은 다음과 같습니다.

var x: Int

var xTimesTwo: Int {
    set {
       x = newValue / 2
    }
    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_B를 얻을 때까지 계속 실행될 것입니다.AD_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
    }
}

게터/세터가 재정의되는 동일한 변수에 액세스하려고 하면 무한 루프가 발생하므로 변수 값을 임시 변수에 유지해야 합니다.

이렇게 간단하게 세터를 호출할 수 있습니다.

x = 10

Getter는 지정된 코드 라인 아래에서 작동할 때 호출됩니다.

var newVar = x

업데이트: 스위프트 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

재귀적으로 정의하고 있습니다.x와 함께x마치 누군가가 당신에게 몇 살이냐고 묻는 것처럼?그리고 당신은 "나는 내 나이의 두 배입니다."라고 대답합니다.그건 의미가 없어요.

당신은 제가 존의 두 배 나이나 당신 자신을 제외한 다른 변수라고 말해야 합니다.

계산된 변수는 항상 다른 변수에 종속됩니다.


일반적으로 게트리 내에서 자산 자체에 액세스하지 않습니다.get그러면 또 다른 사건이 발생할 수 있기 때문에get또 다른... 인쇄하지도 마인쇄를 하려면 먼저 값을 '얻어야' 하기 때문입니다!

struct Person{
    var name: String{
        get{
            print(name) // DON'T do this!!!!
            return "as"
        }
        set{
        }
    }
}

let p1 = Person()

그러면 다음과 같은 경고가 표시됩니다.

자체 getter 내에서 'name'에 액세스하려고 합니다.

오류는 다음과 같이 모호합니다.

여기에 이미지 설명 입력

대안으로 사용할 수 있습니다.didSet.와 함께didSet이전에 설정되어 있고 방금 설정된 값을 유지할 수 있습니다.자세한 내용은 이 답변을 참조하십시오.

사용해 보십시오.

var x:Int!

var xTimesTwo:Int {
    get {
        return x * 2
    }
    set {
        x = newValue / 2
    }
}

이것은 기본적으로 잭 우의 대답이지만, 차이점은 잭 우의 대답에서 그의 x 변수는var x: Int내 x 변수는 다음과 같습니다.var x: Int!그래서 제가 한 일은 그것을 선택형으로 만드는 것뿐이었습니다.

Swift의 설정자 및 설정자는 계산된 속성/변수에 적용됩니다.이러한 속성/변수는 실제로 메모리에 저장되는 것이 아니라 저장된 속성/변수 값을 기반으로 계산됩니다.

다음 주제에 대한 Apple의 Swift 설명서를 참조하십시오.신속한 변수 선언입니다.

여기 이론적인 대답이 있습니다.그것은 여기에서 찾을 수 있습니다.

{getset} 속성은 지속적으로 저장된 속성일 수 없습니다.이 속성은 계산된 속성이어야 하며 get과 set을 모두 구현해야 합니다.

Swift 5.1용 업데이트

Swift 5.1부터는 get 키워드를 사용하지 않고도 변수를 얻을 수 있습니다.예:

var helloWorld: String {
"Hello World"
}

언급URL : https://stackoverflow.com/questions/24025340/property-getters-and-setters

반응형