티스토리 뷰

Swift

속성(프로퍼티) 정복하기 - 4장

swallow.iOS 2022. 7. 3. 03:46

안녕하세요! Swallow입니다!

이번 포스팅은

⭐️ 속성 감시자(Property Observers) ⭐️

관한 글입니다!

항상 어떠한 조언, 충고 환영입니다!

시작하기에 앞서 이 글은

앨런 Swift 문법 마스터 스쿨 강의와 야곰님의 스위프트 프로그래밍 책

공부하고 참고하여 작성하였습니다!

그럼 시작하겠습니다!

 

 

속성 감시자(Property Observers)란?

속성의 값의 변화를 관찰하는 실질적인 메서드이고,

속성의 값이 변하는 순간

해당 속성에서 구현한 속성 감시자가 호출이 됩니다!

대부분 저장 속성의 값의 변화를 관찰하고,

저장 타입 속성, 인스턴스 저장 속성 둘 다 가능합니다!

 

속성 감시자에는 두 가지가 존재합니다!

willSet - 새 값이 저장되기 직전에 호출이 됩니다!

didSet - 새 값이 저장된 직후에 호출이 됩니다!

 

간단한 설명은 여기까지 하고,

예시를 보여드리면서 다시 말씀을 드려볼게요!

 

1. willSet

willSet은 새로운 값이 저장되기 직전에 호출이 됩니다!

newYear은 새로운 값이 newYear이라는 파라미터로 전달이 된다는 것입니다!

하지만!

파라미터가 없이도 속성 감시자를 구현할 수 있습니다!

이 전에 배웠던

newValue로 파라미터를 대체할 수 있습니다!

되게 편리하죠?

 

이제 정의하는 방법은 알았고

사용을 해볼까요?

속성 감시자는

값이 변할 때 호출이 된다고 말씀드렸어요!

age의 값을 변화를 주면!

이렇게 willSet이 호출이 되어서

호출이 될 때 구현한 print함수가 실행이 됩니다!

willSet은 값이 변하기 직전에 호출이 된다고 말씀을 드렸습니다!

값에 변화를 주어도 값이 변하기 직전에 호출이 되기 때문에

print함수에서 출력한 age의 값이

⭐️ 변화를 준 25가 아닌, 이전 값인 24가 된 것입니다! ⭐️

 

2. didSet

기본적인 구현 방법은 willSet과 동일합니다!

didSet은 새로운 값이 저장된 직후에 호출이 됩니다!

willSet의 예시처럼 파라미터를 줄 수도 있고,

위의 예시처럼 oldValue로 파라미터를 대체할 수 있습니다!

 

didSet도 정의 방법은 알았고

이제 호출을 해볼까요?

willSet과 동일하게

age의 값을 변화를 시키면!

didSet이 호출이 되어서

호출될 때 구현한 print함수가 실행이 됩니다!

didSet은 값이 변화된 직후에 호출이 된다고 말씀드렸습니다!

그래서 print함수에서 출력한 age의 값에

⭐️ 변화를 준 25가 저장이 되고, 이 전에 저장이 되어있던 24가 oldValue로 전달이 된 것입니다! ⭐️

 

 

그리고 willSet , didSet 둘 다 동시에 구현이 가능합니다!

willSet , didSet을 같이 구현하고

age에 변화를 주면!

이런 식으로 출력이 됩니다!

값에 변화를 주었으니,

당연히 새 값이 저장되기 직전에 willSet이 호출이 되고,

그 후에 새로운 값이 저장이 되면서

새로운 값이 저장된 직후에

didSet이 호출이 됩니다!

 

그렇기 때문에

print함수 내부에서 age를 보시면

willSet , didSet 둘 다 동일한 age를 출력을 하고 있지만

willSet은 24가 먼저 출력이 되고,

didSet은 25가 먼저 출력이 되고 있습니다!

 

조금 더 쉽게 말씀드리면

willSet의 age는 값이 변하기 전에 호출이 되어서

기존에 존재하던 age의 값이 출력된 것이고,

didSet의 age는 값이 변한 직후에 호출이 되기에

새롭게 저장된 age의 값이 출력된 것입니다!

 

 

속성 감시자의 특징에 대해서 말씀드릴게요!

1. 클래스, 구조체, 열거형에서 모두 사용이 가능합니다! 🔥

2. 저장 속성과 상속에서 재정의 된 계산 속성에서

사용이 가능하며, 대부분 저장 속성에서만 사용을 합니다! 🔥

3. 일반적인 계산 속성에서는 구현이 불가능합니다! 🔥

4. 속성 감시자는 새로 받은 값이 현재의 값과 동일하더라도

속성의 값이 변화될 때마다 호출이 됩니다! 🔥

5. 일반적으로 willSet, didSet을 모두 사용하지 않고

didSet만 사용하는 경우가 많습니다! 🔥

6. 속성 감시자는 let으로 선언이 불가능합니다! 🔥

let은 값이 변하지 않아서, 관찰할 필요가 없기 때문입니다! 🔥

7. 지연 저장 속성은 접근해야 메모리에 올라가니 속성 감시자를 추가할 수 없습니다! 🔥

8. 속성이 변하면, 업데이트를 하려는 패턴을 구현할 때 사용합니다! 🔥

ex) 상태 메시지, 프로필 사진 변경 등등..

 

여기서 일반적인 계산 속성에서는

구현이 불가능하다고 말씀을 드렸습니다!

그 이유는 set블록에서 값의 변경을 관찰할 수 있기 때문입니다!

이렇게 set블록에서

newValue로 받는 값을

기존에 존재하던 name에 할당을 해주고

set블록 자체에서 값이 변경되었을 때,

출력할 print함수를 만들어주면 되기 때문에

계산 속성에서는 속성 감시자가 필요하지 않습니다!

위의 예시처럼

계산 속성의 set블록에서 속성 감시자와 비슷한

기능을 하는 코드를 작성을 한 후

값을 변경해 주면!

이렇게 출력이 됩니다!

 

다시 말씀드리지만, 계산 속성에는

set블록이 속성 감시자의 역할도 가능하기에

속성 감시자가 필요하지 않습니다!

 

 

마지막으로 한 가지 더 말씀드리겠습니다!

위의 예시에서

var age: Int = 24 { }

이 부분이 계산 속성과 비슷해 보일 수도 있습니다!

하지만 계산 속성과는 다르게 기본값을 설정할 수도, 설정을 하지 않을 수도 있습니다!

기본값을 설정하지 않을 경우, 생성자를 통해서 초기화를 진행하면 됩니다!

속성 감시자도 마찬가지로 계산 속성과 같은 실질적인 메서드이지만,

var age: Int = 24 <--- 이 부분처럼

속성 감시자는 저장 속성 밑에 실질적인 메서드를 추가한 형태입니다!

계산 속성은 그냥 실질적인 메서드 형태인 것입니다!

기억해 두시면 좋아요! 😁

 

오늘 준비한 글은 여기까지 입니다!

다음 작성할 글은

⭐️ 메서드(methods) ⭐️

관한 글입니다!

속성처럼 많은 내용을 다룰 예정입니다!

기대해 주세요!

 

감사합니다!

 

피드백 언제나 환영입니다!

댓글