본문 바로가기

iOS/UIKit

@Invalidating과 didSet의 차이

 

저는 동아리에서 디자인 시스템 라이브러리 새로 개발하고 있습니다.

라이브러리 개발이 끝나면 해당 디자인 시스템의 Atom이나 Component를 미리 볼 수 있도록

기존에 있었던 YDS-Storybook과 같은 스토리북을 개발할 예정입니다.

사진처럼 특정 옵션의 값을 변경(왼→오)하면 상단에 보이는 컴포넌트가 실시간으로 업데이트되는 구조를 구현하려고 합니다.

 

이를 위해, 외부에서 변경 가능한 옵션들을 @Invalidating을 사용해 선언했습니다. 하지만, Swift에는 이와 유사하게 프로퍼티 옵저버를 사용해 값의 변화를 감지할 수 있는 didSet도 있습니다.

 

그렇다면, @Invalidating과 didSet은 어떤 차이점이 있을까요?
둘 다 상태 변화를 감지하는 역할을 하지만, 사용 목적과 동작 방식에 차이가 있습니다. 이 두 방법의 차이점을 정리해 보겠습니다.

 

@Invalidating

: Swift에서 제공하는 property wrapper로, 뷰의 특정 부분이 변경되었음을 시스템에 알리고 해당 부분을 무효화하는 데 사용됩니다. 이를 통해 뷰가 다시 레이아웃되거나 다시 그려지도록 할 수 있습니다.

  • 주 목적: 뷰의 특정 상태가 변경되었을 때, 자동으로 시스템에 무효화 알림을 보내서 레이아웃(layout)이나 디스플레이(display) 갱신을 트리거합니다.
  • 사용 예: @Invalidation(.layout)은 레이아웃이 무효화되었음을 시스템에 알려서 자동으로 다시 레이아웃을 하도록 합니다.
  • 예시 동작: 속성 값이 변경될 때, 자동으로 뷰의 레이아웃이나 그리기 작업을 다시 처리하도록 시스템이 알아서 처리합니다.
@Invalidating(wrappedValue: "", .layout, .display) public var text: String

위 코드에서 style이 변경되면 레이아웃이 자동으로 무효화되고, 필요시 레이아웃 갱신 작업이 이루어집니다. 이를 통해 직접적으로 layoutIfNeeded()를 호출할 필요가 없습니다.

 

그러면 display 속성은 무엇일까요 ❓

: 화면이 다시 그려져야 함을 시스템에 알립니다. 이것은 뷰의 시작적 요소(디스플레이)가 변경될 때 사용되며, 주로 뷰의 색상, 텍스트, 이미지와 같은 내용이 변경될 때 사용됩니다.

  • 어떤 경우에 유용할까요?
    • 텍스트나 이미지 등 시각적인 변경이 있을 때
    • 뷰가 다시 그려져야 할 때
  • 효과
    • @Invalidating(.display)를 사용하면 값이 변경될 때 자동으로 화면이 다시 그려집니다. 예를 들어, 텍스트가 변경되면 draw(_:)가 호출되거나 setNeedDisplay()가 자동으로 실행됩니다.

 


didSet

: Swift의 속성 감시자입니다. 속성의 값이 변경될 때마다 직접적으로 특정 작업을 수행할 수 있도록 해줍니다. 이는 속성 변경 시 커스텀 로직을 구현하는데 유용합니다.

  • 주 목적: 속성 값이 변경될 때마다 특정 동작을 수행할 수 있습니다.
  • 사용 예: 속성이 변경될 때 직접적인 작업을 수행하고 싶을 때 사용합니다. 예를 들어, 뷰를 다시 그리거나 레이아웃을 다시 설정하는 작업을 할 수 있습니다.
  • 예시 동작: 속성의 값이 변경될 때매다 didSet 블록 안에 있는 로직이 실행됩니다.
public override var text: String? {
    didSet { layoutIfNeeded() }
}

위 코드에서 text 값이 변경되면, layoutIfNeeded()가 직접 호출되어 해당 뷰의 레이아웃이 다시 계산되도록 명시적으로 요청됩니다. 이 방식은 didSet 내부에 원하는 동작을 구체적으로 명시할 수 있습니다.

 

🔎 결론 

@Invalidating자동으로 레이아웃이나 뷰 갱신이 필요할 때, 즉 시스템에 그 작업을 맡길 때 유용합니다.

didSet은 값이 변경될 때 Invalidating에서 기본으로 호출해주는 메서드 이외에 직접적인 작업이 필요할 때 사용합니다. 예를 들어, 값이 변경될 때마다 특정 계산을 하거나 추가적인 로직을 실행하고 싶을 때 유용합니다.

'iOS > UIKit' 카테고리의 다른 글

Swift로 간단한 2D 게임 만들기(with.SpriteKit)  (1) 2024.12.07