본문 바로가기

카테고리 없음

[Swift]프로퍼티(Properties) 기능들 좀 알아보자!

정확하지 않은 정보가 있을 수 있습니다.

 

프로퍼티(properties)

개념정의로는 속성을 말함, 즉 타입 내에있는 값을 저장 하는 변수나 상수를 일컷는말

프로퍼티는 클래스,구조체, 열거형과 관련한 값이다.

 

[프로퍼티의 종류는 두가지]

- 저장 프로퍼티(값이 존재)

ex)var name: String = "gildong"

- 계산된 프로퍼티(값이 없음) 

ex)var name: String

 

- 저장프로퍼티 - 구조체, 클래스

- 계산된 프로퍼티 - 열거형, 구조체, 클래스

 

# 추가로 프로퍼티 옵저버를 정의해서 값이 변할 때마다 모니터링을 할 수 있다.

# 구조체는 let상수로 선언된 프로퍼티값을 변경할 수 없지만 구조체는 참조타입이기때문에 가능!

 

지연 저장 프로퍼티 (Lazy Strored Properties)

 

이는 값이 처음으로 사용되기 전에는 계산되지 않는 프로퍼티입니다.

 

=> 프로퍼티가 특정 요소에 의존적이어서 그 요소가 끝나기 전에 적절한 값을 알지 못하는 경우에 유용합니다

예시로 외부 데이터를 가져오는 클래스내에 프로퍼티를 생성해야할때, 실제 디스크 파일에서 데이터를 가져오기때문에 초기화시 많은 시간이 소요된다. 이럴 경우 사용전인 lazy를 사용하면 좋다

=> 즉, 지연프퍼를 선언해 놓았기 때문에 실제 그 프로퍼티를 사용하기 전에는 복잡하고 시간일 오래 소요되는 연산을 할 필요가 없다는 것입니다.

# Lazy 상수는 안되고 변수 var만 선언 할 수 있다 => 상수는 초기화가 되기전에 항상 값을 같는 프로퍼티인데 지연프로퍼티는 처음 사용되기전에는 값을 갖지 않는 프로퍼티이기 때문이다.

 

 

계산된 프로퍼티 (Computed Properties)

 

getter와 optional한 setter를 제공해 값을 탐색하고 간접적으로 다른 프로퍼티 값을 설정할 수 있는 방법을 제공합니다.

 

 

 

읽기전용 계산된 프로퍼티 (Read-Only Computed Properties)

 

getter만 있고 setter를 제공하지않는 계산된 프로퍼티를 읽.계.프라고 합니다.

=> 즉 읽계프는 반드시 반환 값을 제공하고 다른 값을 지정할 수 없는 프로퍼티 입니다.

읽기전용은 한번 값이 정해지면 변하지 않기 때문에 let으로 선언하는 것이 맞으나 계산된 프로퍼티는

읽기전용이라 하더라도 계산 값에 따라 변할 수 있기에 var로 선언

 

struct Cuboid {

  var width = 0.0, height = 0.0, depth = 0.0
  var volume: Double {
  	return width * height * depth

	}
}

let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// "the volume of fourByFiveByTwo is 40.0" 출력

 

 

 

=> 그런데 이렇게 보니 메서드가아닌 변수로도 저렇게 값을 리턴해서 사용할 수 있는건가 ???

읽기전용프로퍼티이기때문에 가능한건가 ???..아무튼

 

 

프로퍼티 옵저버 (Property Observers) 

 

프퍼는 새 값이 설정(set) 될 때마다 이 이벤트를 감지할 수 있는 옵저버를 제공합니다.

이 옵저버를 프퍼 옵저버라 하는데 프퍼 옵저버는 새 값이 이전 값과 같더라도 항상 호출 됩니다.

#참고로 지연프퍼에서는 옵저버를 사용할 수 없다. Ex) lazy stored properties x

#계산된 프로퍼티는 setter에서 값의 변화를 감시 할 수 있기때문에 옵저버를 정의할 필요가 없습니다.

 

프퍼옵의 두가지

  • wiliest : 값이 저장되기 바로 직전에 호출 됨, 새 파라미터명을 지정할 수 있음. 지정하지않을시(default: newValue)
  • didset : 새 값이 저장되고 난 직후에 호출 됨, didset에서는 바뀌기 전에 값의 파라미터명을 지정할 수 있음. 지정하지 않을시(oldValue)사용

 

 

NOTE 서브클래스에서 특정 프로퍼티의 값을 설정했을 때, 수퍼클래스의 초기자(initializer)가 호출 된 후 willSet, didSet 프로퍼티 옵저버가 실행됩니다. 수퍼클래스에서 프로퍼티를 변경하는 것도 마찬가지로 수퍼클래스의 초기자가 호출된 후 옵저버가 실행됩니다.

 

 

프로퍼티 옵저버 관련한 예제

 

class StepCounter {

	var totalSteps: Int = 0 {
	willSet(newTotalSteps) {
        print("About to set totalSteps to \(newTotalSteps)")
        }

        didSet {
        if totalSteps > oldValue {

        print("Added \(totalSteps - oldValue) steps")

        }

	}
  }
}

let stepCounter = StepCounter()
stepCounter.totalSteps = 200
// About to set totalSteps to 200
// Added 200 steps

stepCounter.totalSteps = 360
// About to set totalSteps to 360
// Added 160 steps

stepCounter.totalSteps = 896
// About to set totalSteps to 896
// Added 536 steps

=>이벤트사용에 용이한 프퍼옵은 퀘스트 달성했을때나 점수획득했을때 퀘스트에 성공했습니다.~ 점수를 획득했습니다 같은 용도로 사용할 수 도 있을것같다..?

 

타입 프로퍼티 (Type Properties)

 

인스턴스 프로퍼티는 특정 인스턴스에 속한 프로퍼티를 말합니다. 이 프로퍼티는 새로운 인스턴스가 생성될 때마다 새로운 프로퍼티도 같이 생성됩니다. 타입 프로퍼티는 특정 타입에 속한 프로퍼티로 그 타입에 해당하는 단 하나의 프로퍼티만 생성됩니다. 

 

=> 졸려서 이해잘안됨

 

타입 프로퍼티 구문 (Type Property Syntax)

타입 프로퍼티를 선언을 위해서는 static 키워드를 사용합니다. 

클래스에서는 static과 class 이렇게 2가지 형태로 타입 프로퍼티를 선언할 수 있는데 두 가지 경우의 차이는

서브클래스에서 overriding가능 여부입니다. 

class로 선언된 프로퍼티는 서브클래스에서 오버라이드 가능합니다.

 

구조체, 열거형, 클래스에서의 타입 프로퍼티 선언의 (예)는 다음과 같습니다.

 

struct SomeStructure {

    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1

    }

}

enum SomeEnumeration {

    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6

    }

}

class SomeClass {

    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27

    }

    class var overrideableComputedTypeProperty: Int {
        return 107

    }

}

 

NOTE

위의 계산된 타입 프로퍼티의 (예)는 읽기전용이지만, 같은 문법으로 계산된 인스턴스 타입 프로퍼티에서는 읽고 쓸 수 있는 프로퍼티로 사용할 수 있습니다.

 

=> 타입프로퍼티 구문이에서 얻었던 흥미로운 점은 static을 사용해 enum안에서도 값을 넣어서 프퍼를 생성 할 수 있는 것이었다. 추가로 함수처럼 return값도 넣어서 사용할 수있는 이부분이 너무 흥미롭다..

기억해두잣