스터디를 진행하며 처음부터 다시 Swift를 공부하고 있습니다.
오늘 작성할 파트는 클래스와 구조체 입니다.
실제로 면접에서 자주 물어보는 질문 중 하나가 클래스와 구조체라고 합니다.
어느정도는 알고있지만 막상 대답은 못했던.. 이 기회에 다시 알아봤습니다.
Class, Struct의 차이점을 확실히 알고 있다면 성능개선을 할 수 있다고 합니다.
💡 Copy-On-Write?
값 타입 변수를 새로운 변수에 할당할 때, 즉시 새로운 값을 복사하는 것이 아니라,
기존 인스턴스를 계속 가리키다가 변경사항이 생겼을 때 복사본을 만드는 것
struct ValueType { }
class ReferenceType { }
struct ValueType {
var number = 2
}
class ReferenceType {
var number = 1
var structInstance = ValueType()
}
let classInstance = ReferenceType()
let classInstanceCopy = classInstance
classInstanceCopy.number = 0
classInstanceCopy.structInstance.number = 0
print(classInstanceCopy.number) //0
print(classInstanceCopy.structInstance.number) //0
print(classInstance.number) //0
print(classInstance.structInstance.number) //0
참조 타입 인스턴스를 다른 변수에 할당할 때는 참조 값만 전달되기 때문에 내부의 값 타입 인스턴스는
새로 복사되지 않고 기존 인스턴스를 따라갑니다.
클래스 내부에 구조체 인스턴스가 멤버로 있을 때,
변수에 클래스 인스턴스 할당 시 같은 구조체 인스턴스가 따라간다.
struct ValueType {
var number = 2
var classInstance = ReferenceType()
}
class ReferenceType {
var number = 1
}
var structInstance = ValueType()
var structInstanceCopy = structInstance
structInstanceCopy.number = 0
structInstanceCopy.classInstance.number = 0
print(structInstance.number) //2
print(structInstance.classInstance.number) //0
print(structInstanceCopy.number) //0
print(structInstanceCopy.classInstance.number) //0
먼저, 값 타입 할당이 일어났기 때문에 구조체 인스턴스가 새로운 변수에 복사됩니다.
이때, 내부에 있는 값 타입 멤버 변수는 별개의 변수로 복사되고,
참조 타입 클래스 인스턴스는 참조 값이 복사됩니다.
따라서 두 인스턴스의 멤버 변수인 number는 복사본에만 업데이트되고,
클래스 인스턴스는 참조값이 복사되었기 때문에 양쪽 인스턴스에 모두 업데이트됩니다.
구조체 내부에 클래스 인스턴스가 멤버로 있을 때,
변수에 구조체 인스턴스 할당 시 클래스 인스턴스의 참조 값이 따라간다.
디폴트로는 구조체를 사용하라.
스위프트의 구조체는 클래스에서 사용할 수 있는 다양한 요소들을 사용할 수 있습니다.
또한 스위프트의 표준 라이브러리들의 데이터들 대부분 구조체를 사용해 구현되어 있습니다.
Objective-C와 상호 이용(Interoperability) 해야 할 때는 클래스를 사용하라.
Objective-C에서 지원하는 API를 사용해야 할 때는 Objective-C의 클래스를 상속받아야 사용할 수 있습니다.
고유 값을 제어해야 할때는 클래스를 사용하고 제어하지 않는다면 구조체를 사용하라.
주로 파일 관리나 네트워크 연결과 같은 작업을 다룰 때 클래스를 사용합니다.
외부에서 이미 고유성을 처리하고 있는 경우에는
앱 내에서 데이터의 고유성을 관리할 필요가 없습니다.
상속과 공유 속성을 모델링 하고 싶을 때는 구조체와 프로토콜을 사용하라.
앞서 언급했듯이 구조체는 상속이 불가합니다.
하지만 프로토콜을 통해 계층구조를 표현할 수 있습니다.
클래스는 클래스끼리만 상속을 만들 수 있는 반면
프로토콜은 클래스, 열거형, 구조체가 모두 채택하도록 할 수 있습니다.
.
.
.
(수정예정)
https://developer.apple.com/documentation/swift/choosing-between-structures-and-classes