스위프트에는 두 가지 기본 데이터 유형이 있습니다: 값 유형(value types)과 참조 유형(reference types).
struct), 열거형(enum), 기본 유형인 Int, Double, Bool 등이 포함됩니다. 값이 전달되거나 할당될 때 복사되어, 복사본의 변경이 원본에 영향을 주지 않습니다.class)와 관련된 유형입니다. 전달 시 객체 자체가 아니라 객체에 대한 참조가 복사되므로, 하나의 참조를 통해 이루어진 변경이 다른 참조에서도 보입니다.사용법:
CGPoint, CGSize, 상태를 공유하지 않아야 하는 모델).예시:
struct Point { var x: Int var y: Int } class Person { var name: String init(name: String) { self.name = name } } var p1 = Point(x: 0, y: 0) var p2 = p1 p2.x = 10 // p1.x는 여전히 0입니다. var person1 = Person(name: "Alex") var person2 = person1 person2.name = "Sam" // person1.name도 "Sam"이 됩니다.
let이 구조체와 클래스에 대해 어떻게 다른가요? let으로 생성된 class 인스턴스는 완전히 변경 불가능한가요?
답변:
값 유형(struct)의 경우 let은 객체와 그 속성을 변경할 수 없게 만듭니다.
참조 유형(class)의 경우 let은 참조 재지정을 금지하지만 객체의 속성을 보호하지는 않습니다. 속성은 클래스 내에서 let으로 선언되지 않은 경우 변경 가능하다.
예시:
class Box { var value: Int init(value: Int) { self.value = value } } let box = Box(value: 10) box.value = 20 // 괜찮습니다! // box = Box(value: 30) // 오류: box를 재지정할 수 없습니다.
이야기
결제 애플리케이션에서 트랜잭션 모델을 클래스로 정의했지만 상태가 없어야 했습니다. 여러 트랜잭션 목록을 동시에 작업할 때 UI의 여러 부분에서 예측할 수 없는 데이터 편집이 발생했습니다. 각 구성 요소가 자신의 복사본으로 작업할 수 있도록 모델을 구조체로 변경하기로 결정했습니다.
이야기
프로젝트에서 사용자 설정을 클래스에 저장하고 값이 전달되면 복사된다고 생각했습니다. 데이터가 변경될 때 한 화면이 다른 화면에 의도치 않게 영향을 미쳤고, 두 화면 모두 동일한 객체 참조로 작업하고 있었습니다.
이야기
직렬화 모듈에서 모델 데이터를 참조 유형으로 선언했기 때문에 변경 시 캐시의 상태가 손상되었습니다. 값 유형으로 변경한 후 문제는 사라졌고, 각 작업 시 데이터는 독립적으로 유지되었습니다.