본문 바로가기

SwiftUI - self is immutable???

기술적인 이야기/애플 플랫폼 개발 2021. 5. 18.
반응형

SwiftUI 프로그래밍 패러다임에 아직 익숙하지 않다 보니 삽질을 하면서 배우는 게 많은 것 같다. 이번 글의 주제는 제목처럼 가변적인 내(?)가 뭐가 문제인가 하는 내용이다.

728x90

우선 간단한 예제를 보자. 아래의 예는 특정 SwiftUI 뷰 구조체인데 뷰가 표시될 때 타이머를 돌려서 주기적으로 뭔가를 하기 위한 코드이다.

struct SomeView: View {
    var timer: Timer? = nil

    var body: some View {
        VStack {
            Text("Timer!")
        }
        .onAppear {
            // compile error
            timer = Timer()
        }
    }
}

위에서 timer = Timer() 코드 부분에서 아래와 같은 오류가 발생한다.

Cannot assign to property: 'self' is immutable

내가 나를 주무르는데 누가 뭐라 그러면 기분은 참 나쁠 것 같다(?)

Swift에 어느 정도 익숙하다면 구조체(struct)가 멤버 프로퍼티를 업데이트하려면 mutable 속성을 붙여야 한다는 점 정도는 알고 있을 것이다. 그런데 문제는 위와 같은 코드 구조에서는 도대체 어디가 Mutable Updater가 될 수 있을까? 아무리 생각해봐도 별도의 메서드를 분리해서 그걸 mutable로 만드는 수 외에는 이상한 모양이 될 것만 같다.

당연하게도 복잡하고 이상한 코드는 싫다. 좀 더 이 모양을 그대로 유지하고 싶어 졌다. 방법이 없을까?

해결

의외로 쉬운 해결 방법이 있었다. 단순무식하게 해당 프로퍼티를 @State로 만들어버리면 된다.

struct SomeView: View {
    @State var timer: Timer? = nil

    var body: some View {
        VStack {
            Text("Timer!")
        }
        .onAppear {
            timer = Timer()
        }
    }
}

@State 속성을 붙이는 순간 해당 프로퍼티는 이제 이 뷰의 상태가 되고 업데이트가 자유로워진다. 따라서 이제 timer 멤버에 인스턴스를 넣거나 뭔가 다른 이상한 것(?)을 넣는 코드도 아무 문제가 없다.

처음에는 State화 시키는 것이 어색하고 이상한 느낌이 들긴 했는데 생각보다 나쁜 디자인은 아닌 것 같다. 어쨌든 이게 SwiftUI의 멤버를 관리하는 패러다임 중 하나라는 것을 기억해야겠다.

관련된 링크들

 

SwiftUI 오류 유형

SwiftUI 코드를 사용하다 종종 겪게 되는 오류 유형을 정리하는 글

seorenn.github.io

728x90
반응형

댓글