Copy On Write은 컴퓨터 프로그래밍에서 복사 동작을 할 때, 실제 원본이나 복사본이 수정되기 전까지는 복사를 하지 않고 원본 리소스를 공유한다. 원본이나 복사본에서 수정이 일어날 경우, 그때 복사하는 작업을 한다.
흔히 컴퓨터 프로그래밍에서 Copy On Write는 이렇게 정의됩니다.
하지만 swift 환경에서 어떻게 동작하는지 보려면 구현된 코드를 한 번 살펴봐야겠죠?
@propertyWrapper
struct CopyOnWrite<Value: Copyable> {
init(wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
var wrappedValue: Value
var projectedValue: Value {
mutating get {
if !isKnownUniquelyReferenced(&wrappedValue) {
wrappedValue = wrappedValue.copy()
}
return wrappedValue
}
set {
wrappedValue = newValue
}
}
}
Apple > swift > ... > property_wrappers.swift에서 찾은 구현부입니다.
@propertyWrapper
는 무엇일까요?@propertyWrapper
는 swift5.1부터 나온 개념으로 자세한 내용은 Swift Documentation - Property Wrappers에서 확인 가능합니다.
간단하게 정리하자면...
Propery Wrapper를 붙여 한번만 정의해주면 이후 다른 프로퍼티들에서 해당 Property Wrapper를 적용하면 깔끔하게 코드를 재사용할 수 있습니다.
저도 문서만 읽으니 감이 잘 안 오는데요😵💫
나중에 기회가 된다면 더 자세하게 파보도록 하겠습니다🕵️
isKnownUniquelyReferenced(_:)
는 무엇일까요?Apple Developer - isKnownUniquelyReferenced(_:)에서 자세한 내용을 찾아볼 수 있습니다.
docs의 목록에서 알 수 있듯이, 컬렉션 타입의 버퍼를 관리하는 메서드로 보입니다.
isKnownUniquelyReferenced(_:)
는 주어진 개체가 단일 강력한 참조를 갖는 것으로 알려져 있는지 여부를 나타내는 부울 값을 반환합니다.isKnownUniquelyReferenced(_:)
는 주어진 객체에 대한 강력한 참조만 확인합니다. 객체에 추가적인 약하거나 소유되지 않은 참조가 있는 경우 결과는 여전히 true일 수 있습니다. 약한 참조와 소유되지 않은 참조는 객체에 대한 유일한 참조일 수 없기 때문에 약한 참조나 소유되지 않은 참조를 객체로 전달하면 항상 false가 됩니다.isKnownUniquelyReferenced(_:)
함수는 값 타입의 deep storage을 위한copy-on-write
최적화를 구현하는 데 유용합니다.
다시 위의 코드로 돌아가보면, 유일한 참조가 아닐 때(수정이 일어날 때) isKnownUniquelyReferenced(_:)
는 false가 반환되어 copy()
를 통한 복사가 일어나 copy-on-write
가 일어나는 거였네요!
휴... 근데 이걸 면접에서 이야기하기에는 너무 긴 거 같네요!
물론 꼬리 질문에서 "제가 이렇게 코드를 해부해봤는데~"라며 이야기해도 좋지만 처음부터 답하기에는 너무 딥하게 왔습니다.
Swift에서는 String과 Collection Type을 복사해서 사용할 때 일어납니다. 값에 대한 수정이 일어날 때 복사하는 기능으로, 변경되기 전에는 참조를 통해서 불필요한 복사를 줄여서 메모리를 아낄 수 있습니다.
정도로 대답을 준비할 수 있겠네요!