willSet , didSet 에 대하여

sonny·2024년 9월 27일
2

TIL

목록 보기
7/52

오늘 팀원이 계좌관리 시스템 구축 과제를 했는데 내가 한 것과 달라서 궁금하여 이참에 TIL거리로 삼아 공부하기로 했다.

코드를 쓴 걸 보다가 willSet이라는걸 봤는데 팀원의 블로그 글 중 마지막에 'willSet을 사용하던 didSet을 사용하던 출력은 같다' 라고 하여 비교도 해보고 어느 상황에 많이 사용하는지도 알아보고 싶었다.

willSet

willSet"곧 바뀔 거야"라고 미리 말해주는 것

  • willSet은 값이 바뀌기 전에 실행되고, 예를 들어 친구가 나한테 "이제 곧 사과를 줄 게" 라고 말하는 것과 비슷하다. 값이 바뀌기 전에 그 값이 뭐로 바뀔지 먼저 알려주는 것이다.

didSet

didSet"바뀌었어!" 라고 알려주는 것

  • didSet은 값이 바뀐 후에 실행되고, 예를 들어 친구가 "나 이제 사과를 먹었어!" 라고 말하는 것처럼 이미 바뀐 상태를 알려주는 역할을 하는 것이다.
var appleCount: Int = 5 {
    willSet {
        print("사과가 곧 \(newValue)개로 바뀔 거야!")
    }
    didSet {
        print("사과가 \(oldValue)개에서 \(appleCount)개로 바뀌었어!")
    }
}

appleCount = 7

코드 중 oldValue는 함수가 아니라 프로퍼티 감시자에서 자동으로 제공되는 특별한 변수이다.

oldValue는 이전의 값을 가리키는 변수이고, 새로 값이 설정될 때 자동으로 그 이전 값을 저장하게 된다. 그래서 appleCount5에서 7로 변경될 때, oldValue는 자연스럽게 변경 전 값인 5가 된다.

  • willSet새로 바뀔 값newValue를 미리 말해준다.
  • didSet바뀌기 전의 값oldValue지금 값 appleCount를 알려준다.

간단 요약

willSet : " 곧 바뀔 거야! " (값이 바뀌기 직전에 실행)
didSet : " 바뀌었어! " (값이 바뀐 후에 실행)

응용해보기

아래 코드는 클래스에 여러 가지 기능을 추가하고 didSet을 이용해 여러 상태변경을 바로바로 확인할 수 있도록 해본 것이다.

음..

willSetdidSet을 공부하면서 프로퍼티의 변화 과정을 관리하는 기능이 얼마나 중요한지 조금은 알게 되었다. 처음에는 단순히 값을 변경하고 그에 따라 특정한 코드를 실행하는 것이라고 생각했는데 실제로 다양한 상황에서 유용하게 활용될 수 있다는 점이 꽤 흥미로웠다.

우선, willSet은 값을 변경하기 직전의 상태를 추적하고 어떤 값으로 바뀔지 미리 알고 대응할 수 있다는 것이 큰 장점인데 특히 값이 바뀌기 전에 특정 조건에 따라 미리 경고를 주거나 준비 작업을 해야 할 때 매우 유용하게 쓸 수 있다는 점에서 기본적인 어플에서 많이 봤던 팝업들이 생각났다.

반면, didSet은 값이 변경된 후 그 변화를 추적하고 그에 맞는 후속 작업을 처리하는걸 순조롭게 해주는 것 같다. 어떤 값이 변경되었는지 그리고 oldValue 와 현재 상태도 비교해서 그에 따라 추가적인 작업을 수행할 수 있었다. 게임 시스템처럼 특정 목표에 도달했을 때 이걸 바로 반영하여 승리 메시지를 출력하거나 특정 레벨업을 제공하는 것처럼 상태 변화에 따른 직관적인 반응을 구현할 수 있는 점이 매력적이었다.

이 두 가지 기능은 각각 프로퍼티가 변하기 전과 후의 시점에서 다른 역할을 맡고 있기 때문에 사용 목적에 따라 적절히 조합하여 활용할 수 있다는 것도 재미있었다. 물론 둘 다 값의 변화를 관리하는 데 유용하지만 언제 변화를 감지하고 어떤 시점에서 코드를 실행할지를 고민하면서 적절하게 설계해야 한다는 점이 중요하다는 것도 알게 된 것 같다.

그래도 이 두 가지를 잘 이해하고 사용하면 앞으로 더 효율적인 것을 만들 수 있겠다는 자신감도 얻었다. 실제로 활용해보고 적재적소에 사용하는 연습도 해보려한다.

그리고 마음 한켠에 있는 게임을 만들고 싶다는 작은 욕망으로 player를 나 자신으로 설정 해봤는데, 저거 해보겠다고 시간이 꽤 지나버렸다. 다음에는 willSet도 섞어서 온도 조절 시스템을 만들어보려고 한다.

TIL 개당 100포인트라고 생각하며 저 코드처럼 꾸준히 레벨업 하는 사람이 되고싶다 !


9/29 추가내용

댓글의 scorelevel 연동을 한번 도전 해봤다.

score가 변경될 때마다 didSet이 호출되고, 그 안에서 자동으로 level이 업데이트된다. 여기서는 점수가 100점 이상일 때마다 레벨이 1씩 올라가도록 설계하였다. 점수 100점당 레벨 1로 설정했다.

leveldidSet을 통해 자동으로 변화를 추적해서 이전 레벨과 새 레벨을 비교해준 뒤 출력한다. 이 방식으로 레벨업을 함수로 따로 처리하지 않고도 점수에 따라 레벨이 자연스럽게 변경될 수 있다.

그리고 Point 메서드를 통해 포인트를 추가할 때 자동으로 score가 변경되고 그에 따라 level도 함께 업데이트 되도록 했다. 레벨업이 자동화되어서 점수 변화에 따라 레벨이 자연스럽게 설정 될 수 있도록 !

그래서 levelUp 같은 별도의 수동적인 메서드 없이도 점수에 따라 레벨이 자동으로 계산되니까 코드가 더 간결해지기도 했고, 새로운 규칙이 생기면 scoredidSet 안에서 간단히 점수와 레벨의 관계도 수정할 수 있다.

profile
iOS 좋아. swift 좋아.

2개의 댓글

comment-user-thumbnail
2024년 9월 27일

levelup을 함수로 따로 빼지 않고 레벨별 점수를 설정해서 score의 didSet에 넣어보는 것도 좋을 거 같아요~

1개의 답글