23.10.27 프로퍼티 옵저버(Property Observer)didSet, willSet 의 개념 / bound&frame 의 차이점

2023. 10. 27. 16:22IOS [ 개념정리 ]

프로퍼티 옵저버(Property Observer)는 Swift 언어의 기능 중 하나로,

클래스, 구조체, 또는 열거형의 저장 프로퍼티의 값 변화를 감시하고 그에 따른 동작을 수행할 수 있게 해준다.

 

자 , 일단 프로퍼티옵저버 라는 개념조차도 생소할텐데 ,

값 변화를 감시한다는게 무슨의도를 가지고 어떤상황에 쓰는건지 감도 안올 것 이다.

 

먼저 프로퍼티란

 

변수 또는 상수의 일반화된 용어로,

클래스, 구조체, 열거형 등의 데이터 구조 내에서 데이터를 저장하거나 제공하는 역할을 한다.

 

고로

// 저장 프로퍼티

struct Person {
    var name: String // 저장 프로퍼티
    let age: Int     // 저장 프로퍼티 (상수)
}

// 계산 프로퍼티

struct Circle {
    var radius: Double // 저장 프로퍼티
    var area: Double { // 계산 프로퍼티
        return Double.pi * radius * radius
    }
}

위의 코드와 같이 저장소로 쓰기도하고 , 저 저장소를 활용하여 제공하기도 한다.

예를들어 저기 Person 이라는 struct 를 만든 의도에 대해서 설명을 해보자면,

 

어플을만들때 사람에 대한 정보가 필요한 어플이 분명 있을텐데,

그 정보들을 일일히 다 써주기란 고난도의 노동일 것이다.

 

고로 Person(사람) 이라는 구조를 만들어서 , 

' 사람 ' 이라는 데이터 구조에는 뭐가필요한지 직접 파악하고,

( 여기서는 이름이랑 나이정도로 예시를 듬 ) nameage 라는 저장 프로퍼티를 가진 구조체( struct )를 형성하게끔 하면 

nameage라는 저장프로퍼티를 가진 Person이라는 구조체의 형태가 완성 되는 것 이다.

 

.

.

 

그럼 다시 돌아와서 , 프로퍼티 옵저버에대해서 말해보자면

옵저버 (observer) 라는 단어 자체가 감시의 의미를 가졌기때문에 , 프로퍼티를 감시한다는 의미인데

도대체 이 프로퍼티의 값 변화를 감시한다는게 무슨 의미일까? 

 

먼저 프로퍼티 옵저버는 두가지종류로 나뉜다 .

willSet ( 프로퍼티 값이 변경되기 직전에 호출 )

didSet ( 프로퍼티 값이 변경된 직후에 호출 )

 

아마 코딩을 처음접하고 프로퍼티 옵저버를 처음 접해보면

도대체 프로퍼티 값이 변경되기 직전에 호출하고 변경된 직후에 호출을 하는게

무슨의미가 있을까? 라는 의문이 들것이다.

 

보통 우린 이런경우에 간략한 예시를 통해 사용성과 사용하는 이유 & 의도를 파악할 수 있게될테니 예시를 가져와보겠다.

 

// 값의 변화를 모니터링: 프로퍼티 옵저버( willset , didset )는 프로퍼티의 값이 언제, 어떻게 변경되는지 추적할 수 있다. 
// 이것은 디버깅, 로깅 및 성능 모니터링에 유용하다.

class TemperatureMonitor {
    var temperature: Double = 0 {
    // 프린트 문을 통해서 , 프로퍼티값이 변경되는 시점을 추측할 수 있다.
        willSet {
            print("온도가 \(temperature)도에서 \(newValue)도로 변경됩니다.")
        }
    }
}

// 값의 제약을 적용: willSet을 사용하여 프로퍼티 값이 특정 범위 내에 있는지 확인하고, 
// 범위를 벗어난 경우 새로운 값으로 대체할 수 있다.

class SafeTemperatureMonitor {
// 온도의 기본 설정 값 = 0 
    var temperature: Double = 0 {
        willSet {
        // 만약 변경된 프로퍼티 값이 -30 보다 작으면 
            if newValue < -30 {
            // 온도는 -30도로 표시된다
                temperature = -30
                        // 또는, 변경된 프로퍼티 값이 50 보다 크면 
            } else if newValue > 50 {
                        // 온도는 50도로 표시된다
                temperature = 50
            }
        }
    }
}

// UI 업데이트: didset을 사용하여 프로퍼티 값이 변경될 때 UI를 업데이트하거나
// 다른 연관 작업을 수행할 수 있다.

class ProfileViewController: UIViewController {
// userName을 사용자가 설정하는값으로
    var userName: String = "" {
        didSet {
        // userNameLabel.text 에다가 설정한 값의 이름을 출력한다
            userNameLabel.text = "안녕하세요, \(userName)님"
        }
    }
    @IBOutlet weak var userNameLabel: UILabel!
}

//  데이터 일관성 유지: 프로퍼티 값이 변경될 때 다른 연관된 프로퍼티 또는 데이터를 업데이트하여 
//  데이터 일관성을 유지할 수 있습니다.

struct Circle {
// 원의 반지름이 0이 될때
    var radius: Double = 0 {
    // updateArea의 메서드(함수)를 실행한다
        didSet {
            updateArea()
        }
    }
    // area의 기본값은 0이며,
    private var area: Double = 0
// updateArea 메서드는 다음과 같다.
    private mutating func updateArea() {
        area = Double.pi * radius * radius
    }
}

 

매 코드 한줄한줄마다 설명을 써놓아서 충분히 이해가 됬으리라고 생각된다 ! 

 

결국 정리를해보면 , 프로퍼티 옵저버는 말그대로 , 프로퍼티의 값이 변경되는것을 감지하여,

프로퍼티값이 언제 변경됐어요!! 라던가 이 프로퍼티값이 30으로 바뀌었으니 a라는 기능을 실행할게요 !! 하는 식의 설정값이라고 보면될 것 같다.

 

( 내 설명은 완전 초보자도 알아들을 수 있는 설명이 의도라서 , 보다 자세한 내용은 다른문서를 참고!! )

.

.

.

 

다음은 boundframe 의 차이이다.

 

먼저 개인적으로 bound 를 알려거든 frame을 먼저 알아야된다고 생각된다 

 

frame은 정말 간단하다.

설명을 위한 아이폰 투명 배경

많이 보던 핸드폰 화면이다.

이 핸드폰 화면위에는 y가 있고 왼쪽엔 x가 있다.

x는 가로줄의 좌표, y는 세로줄의 좌표를 나타내는데, 두가지 모두 왼쪽과 위쪽에 딱 달라붙어있기때문에 현재 값이 0 인것이다.

그렇다 x와 y좌표는 왼쪽과 위쪽기준으로 시작된다.
그리고 그 기준이 되는 핸드폰화면을 superView라고 한다.

 

( superView를 기준으로 UI를 잡는경우가 많기때문에 잘 알아둘것 )

 

이렇게 핸드폰 화면을 기준으로 , 내 핸드폰 맨위쪽은 y = 0 , 내 핸드폰 맨왼쪽은 x = 0 과 같이 표현하는게 superView를 기준으로 한 frame이다 🥰

같은 맥락으로 , 내가 만약에 UIView를 하나 넣었고 , 그 UIView에서 오른쪽으로 10정도 떨어트린 UILabel을 만들고싶다 !! 

그러면 그것은 UIView를 기준으로 한 frame이 되는것이다.

 

고로 frame은 상위에 있는 View를 기준으로 위치선정이 가능한 단위라고 보면된다 !

 

자 그럼 대망의 bound가 뭘지 알아보자

 

frame은 상위에 있는 ( 가장 최상위는 superView ) View 에 의해서 위치가 결정되는 반면,

bound는 자기자신만의 위치좌표값을 가지는 단위라고 보면된다.

출처 : zedd0202님 블로그

설명하기 너무 좋은 예제가 있어 모셔왔다!

단순히 이 짤방만 보면 무슨생각이드는가? 

 

frame을 공부한 우리는

"아 ~ 파란색View의 frame값을 살짝 왼쪽위쪽으로 옮겼구나~ "

하는 생각이 들거라고 생각한다

 

하지만 사실 이 짤방의 좌표를 옮긴것은 빨간색View이다.

 

아~~~~~~주 큰 무한대의 종이위에 저 빨간색&파란색이 겹쳐진 종이가 올려져있다고생각해보면 이해가쉽다.

( 노란색은 핸드폰 배경전체를 나타낸것 )

그 큰 종이 위에서 핸드폰프레임안의 ( 노란색 ) 저 빨간색의 bound값을 조정하면 , 보통 노란색 안에서 빨간색이 이동하는것이 맞는데,

bound를 쓰는여기서는 아예 핸드폰 프레임( 노란색 ) 자체를 이동시켜 버리는것이다.

 

즉 아주 큰 무한대의 종이 위에서 , originbound값을 빨간색에다 부여할시,

그 무한대의 종이위에서 빨간View가 originbound값만큼 이동하고,

그 이동한곳에서 다시 0,0의 좌표값을 가지는것이다.

 

아마 이해하기 어려울듯

이 내용에 대해 잘 알고싶으면 zedd0202님 블로그에 아주 멋지게 설명되어있으니 참고!