iOS단톡방에서 재미있는 주제로 이야기를 하는걸 보았음. 값타입의 CoW에 대해 알고는 있었는데, 단 한번도 아래 사진과 같은 의문은 가져본적이 없었고, 실험 결과가 너무 재미있어서 한번 정리해보았음.
기존에 알고 있던 CoW는 값타입의 객체를 복사하면 메모리 효율을 위해 일단 주소값을 복사하여 갖고있다가, 수정이 일어날 때 새로운 인스턴스를 만들어 할당하는 내용이엿음.
arr1을 만들고 arr2에 arr1을 복사하였을 때, 이때 주소가 같은건 Ok.
arr2에서 수정이 일어났을때 새로운 인스턴스 할당하는거 OK.
그런데,, arr1에서 수정이 일어났을 땐?
기존의 생각으로는 arr2는 arr1의 복사본이라는 개념으로 접근하다보니 arr2가 바뀌어야 할 것 같았는데, 실제 실험 결과 arr1의 메모리 주소가 바뀌었음 (새로운 인스턴스가 할당되었다)
그러나 내 의문은 arr2에 다시 append하였을때 또 메모리 주소가 바뀌는걸 볼 수 있었다.
분명 arr2에 append하기 전에 arr1이 append가 되어 이제 유일한 레퍼런스를 독차지 했음에도 왜 arr2에 append하면 이미 독차지한 주소를 버리고 왜 새로 할당을 받는것인가?
가설 2의 경우 다음과 같은 실험을 통해 아니라는걸 알 수 있었다.
구글링과 단톡방에서 공유했었던 링크들에 들어가보니 Swift String(Array) 성능 최적화에서 다른 실마리를 찾을 수 있는데, Swift에서 배열은 크기보다 더 많은 크기를 예약해놓고 사용하고, 그 크기를 전부 다 사용하였을 경우 새로운 메모리주소로 간다.
순간 이거였나 싶었는데,
1000개를 추가했는데에도 3-4번정도만 메모리 주소가 바뀌었음. arr1과 2가 공유했던 그 자리에는 배열을 선언 후 한번도 사용하지 않았기 때문에 분명 예약된 메모리 주소가 많았을텐데, 왜 겨우 한번에 메모리 주소가 변경되었을까?
확실한 실마리를 찾으면 돌아오겠습니다...