반응형
우리가 모르고 쓰는 writeback 최적화
Swift에서 struct
는 값 타입이라, 배열에 담긴 struct를 수정하려면 "복사 → 수정 → 재할당"이 기본입니다.
하지만 가끔 이렇게 코드를 짰는데도… 잘 됩니다?
users[index].profile.updateNickname("newName")
분명 struct인데도 내부 값을 이렇게 바꿨는데 잘 된다?
어떻게 가능한 걸까요?
struct User {
var id: Int
var profile: Profile
}
struct Profile {
var nickname: String
mutating func updateNickname(_ newNickname: String) {
nickname = newNickname
}
}
그리고 배열
var users: [User] = [
User(id: 1, profile: Profile(nickname: "Alice")),
User(id: 2, profile: Profile(nickname: "Bob"))
]
이 상황에서 아래 코드가 에러 없이 실행됩니다.
users[1].profile.updateNickname("Bobby")
User도 Profile도 struct, 즉 값 타입인데도 컴파일 에러 없이 잘 작동합니다.
writeback 최적화란?
Swift 컴파일러는 이런 상황을 위해 "writeback 최적화" 라는 걸 제공합니다.
위 코드는 내부적으로 아래처럼 처리됩니다:
var temp = users[1] // 복사
temp.profile.updateNickname("Bobby")
users[1] = temp // 수정한 값을 다시 할당
즉, 우리가 재할당하지 않았지만 Swift 컴파일러가 자동으로 해준 것입니다.
하지만 주의할 점
이 최적화는 항상 작동하지 않습니다.
예를 들어 아래와 같은 경우는 동작하지 않을 수 있습니다:
getUsers()[1].profile.updateNickname("Bobby") // 함수에서 리턴된 배열 → writeback 불가
는 다음처럼 배열 대신 딕셔너리 등을 사용하는 경우도 예외입니다.
게다가 Swift의 향후 버전에서 내부 최적화 전략이 바뀔 가능성도 있습니다.
그래서 아래처럼 명시적으로 처리하는 방식을 권장합니다.
var user = users[1]
user.profile.updateNickname("Bobby")
users[1] = user
마무리
writeback 최적화는 Swift가 제공하는 똑똑한 기능이지만,
우리가 직접 컨트롤할 수 없는 부분에 의존하는 코드는 언제든 위험 요소가 될 수 있습니다.
반응형
'Programming > Swift' 카테고리의 다른 글
Swift OptionSet으로 깔끔한 옵션 관리하기 (0) | 2025.03.24 |
---|---|
Actor가 처음이라고요? (0) | 2025.01.01 |
swift 주석 관련 공식 문서 (Swift Markup Formatting Reference) (0) | 2024.08.01 |
MVVM+Router (0) | 2024.04.18 |
[SwiftUI] 애플에서 제공하는 LazyVGrid 구현 예제 (0) | 2023.07.03 |