[Swift] 프로퍼티, 프로퍼티 옵저버

Kiwi·2024년 3월 13일

Swift

목록 보기
11/21
post-thumbnail

📁 프로퍼티

프로퍼티는 타입 내부에 정의된 상수나 변수이다. 크게 저장 프로퍼티와 연산 프로퍼티로 나뉘는데 더 상세하게 정리해보자!

📝 저장 프로퍼티 (stored property)

일반적으로 사용하는 프로퍼티이다. 인스턴스나 타입의 변수 또는 상수로 값을 저장하는데 사용된다. 클래스, 구조체, 열거형에서 모두 사용되며 일반적으로 클래스와 구조체 내부에 선언된다. 초기값을 가질 수 있다.

struct Person {
	var name: String //저장 프로퍼티
}

📝 지연 저장 프로퍼티 (lazy stored property)

지연 저장 프로퍼티는 lazy 키워드를 사용한다. lazy 키워드로 프로퍼티를 정의하면 프로퍼티가 처음 사용되는 시점에 초기화가 이루어진다.

struct Person {
	var name: String = "jimmy" //저장 프로퍼티
    lazy var nickname: String = "adorable" + self.name //지연 저장 프로퍼티
}

이러한 지연 저장 프로퍼티는 다음과 같은 특징이 있다

1. 의존적인 값을 할당할 수 있다.

struct Person {
	var name: String = "jimmy" //저장 프로퍼티
    var nickname: String = "adorable" + self.name //error
}

프로퍼티는 타입이 초기화 되기 전에는 사용할 수가 없다. 즉 위의 예시와 같은 경우에도 Person이라는 구조체가 선언되지 않은 상태이기 때문에 에러가 발생한다. 하지만 지연 저장 프로퍼티를 사용하면 자신의 프로퍼티의 값을 또 다른 프로퍼티에서 사용할 수 있다. 왜냐하면 지연 저장 프로퍼티를 처음 사용하여 초기화 되는 시점은 인스턴스가 생성된 다음이기 때문이다.

struct Person {
    var name: String = "jimmy" //저장 프로퍼티
    lazy var nickname: String = "adorable" + self.name //지연 저장 프로퍼티
}

var ally: Person = Person()
print(ally.nickname) //adorablejimmy
ally.name = "mike"
print(ally.nickname) //adorablejimmy

2. 변수로만 선언할 수 있다.

지연 저장 프로퍼티는 lazy var로 선언해줄 수 있다. lazy let은 사용할 수 없다. let은 상수로 한번 초기화 되면 그 값이 변하지 않는다. 그렇기에 초기화를 지연시키는 lazy 와는 설계상 불가능 하다.

📝 연산 프로퍼티 (computed property)

말 그대로 연산된 프로퍼티를 말한다. 연산 프로퍼티는 직접적으로 값을 저장하는 것이 아니라 값을 계산하는데 사용된다. (말로만 들으면 엥 싶다) 연산 프로퍼티는 get과 set을 사용하여 정의된다. get 블록은 프로퍼티의 값을 가져오는 역할을 하고, set 블록은 값을 설정하는 역할을 한다. set 블록은 필수가 아니며 읽기 전용 연산 프로퍼티를 만들때는 get 블록만 정의하면 된다. 연산 프로퍼티는 그 때 그 때 계산한 값을 알려주기 때문에 변수를 나타내는 var를 사용하여 선언한다.

struct Circle {
	var r: Double
    var area: Double{
    	get {
        		return Double.pi * r * r
        }
        set (newArea) {
        	r = sqrt(newArea / Double.pi)   //// 주어진 넓이로부터 반지름을 다시 계산하여 설정
        }

위의 코드에서는 area의 값을 얻어올때는 get블록을 통해 넓이를 얻어오고, set 블록을 통해 새로운 넓이를 할당할 수 있다. 새로운 넓이를 할당하면 그에 따라 반지름 r 값도 변할 것이다.

var myCircle = Circle(radius: 3.0)
print(myCircle.area)	//get
myCircle.area = 50		//set
print(myCircle.radius)

📁 프로퍼티 옵저버

앞서서 연산 프로퍼티로 프로퍼티끼리 의존적으로 만들 수 있었다면 , 프로퍼티 옵저버는 프로퍼티를 관찰하여 특정 프로퍼티의 값 변경 전후에 추가 동작을 수행할 수 있다. didSet은 새 값이 저장된 직후에 호출되고, willSet은 값이 저장되기 직전에 호출된다. didSet에서 새로운 값 이전의 프로퍼티 값이 oldValue로 제공되고, willSet에서는 새로운 프로퍼티의 값이 newValue로 제공된다.

var name: String = "Unknown" {
    willSet {
        print("현재 이름 = \(name), 바뀔 이름 = \(newValue)")
    }
    didSet {
        print("현재 이름 = \(name), 바뀌기 전 이름 = \(oldValue)")
    }
}
 
name = "Peter"

//현재 이름 = Unknown, 바뀔 이름 = Peter
//현재 이름 = Peter, 바뀌기 전 이름 = Unknown

willSet보다는 didSet이 많이 사용되며, willSet과 didSet을 둘 다 작성했을 경우 willSet이 먼저 실행된다. 프로퍼티 옵저버는 저장 프로퍼티와 연산 프로퍼티에 추가할 수 있다.

profile
🐣 iOS Developer

0개의 댓글