klioop for iOS

value type vs reference type 본문

swift

value type vs reference type

klioop2@gmail.com 2021. 3. 17. 19:37

Swift 에서는 각 자료형을 구분하는 type 뿐만 아니라 자료의 성격을 구분하는 type 도 존재한다. (맞는 표현인가?)

value type 과 reference type 이 그것이다.

 

아주 대표적으로 struct 와 class 의 비교는 이 둘의 차이점을 잘 드러낸다.

struct 은 value type 이고 class 는 reference type 이다.

기본적으로 사용하는 int, floating point, string, array 등 은 value type 이고 모두 struct 으로 만들어졌다.

 

결론부터 이야기 하자면 value type 인 struct 의 instance 가 변수나 상수에 저장되거나 함수의 인자로 사용될 때 해당 값(value)은 그대로 복사된다. 반면에, class 의 instance 의 경우는 해당 값을 저장 하고 있는 메모리 주소가 참조된다.

 

struct Enemy {
    var health : Int

    mutating func beingAttacked (damage: Int) {
        health -= damage
        print("The damage is \(damage). Now, the health is left, \(health)")
    }
}

var skeleton1 = Enemy(health: 100)
var skeleton2 = skeleton1

skeleton1.beingAttacked(damage: 10)

skeleton1.health // 90
skeleton2.health // 100

 

위 코드에서 skeleton2 는 skeleton1 이 가지고 있는 값들을 그대로 복사해서 새로 생성된다. 그래서 skeleton1 이 10 의 피해를 받았을 때 새롭게 생성된 skeleton2 의 체력은 100 으로 그대로 유지된다. 하지만 Enemy 를 reference type 인 class 로 정의해서 같은 상황을 연출하면 전혀 다른 결과가 나타난다.

 

class Enemy {
    var health : Int

    init(health: Int) { self.health = health }

    func beingAttacked (damage: Int) {
        health -= damage
        print("The damage is \(damage). Now, the health is left, \(health)")
    }
}

var skeleton1 = Enemy(health: 100)
var skeleton2 = skeleton1

skeleton1.beingAttacked(damage: 10)

skeleton1.health // 90
skeleton2.health // 90

 

skeleton2 에 skeleton1 을 할당하면 skeleton2 변수는 skeleton1 의 properties 와 method 를 저장하고 있는 메모리를 "참조" 하게 된다.

그렇기 때문에 skeleton1 이 10 의 피해를 입으면 같은 주소를 참조하고 있던 skeleton2 의 health 도 90 으로 깎이게 된다. 변수명만 다를 뿐 skeleton1 과 skeleton2 는 같은 메모리 주소를 참조하고 있기 때문이다.

 

사진으로 비유된 좋은 예시가 하나 있다.

value type 을 다루는 것은 내 사진 한 장을 그대로 복사해서 친구에게 주는 것과 같다. 친구가 그 복사한 사진을 찢거나 낙서를 해도 내가 가진 사진은 당연히 멀쩡할 것이다. 사진을 복사해서 아무리 많은 사람들에게 나누어 주어도 내가 직접 사진을 수정하지 않는다면 내가 가지고 있는 사진은 멀쩡하다.

 

반면, reference type 의 경우, 사람들에게 내 사진이 저장된 클라우드의 주소를 알려주는 것과 같다. 주소를 공유하면서 파일을 수정할 수 있는 권한도 함께 준다고 가정해보자. 주소를 공유받은 누군가 한 명이라도 저장되어 있는 사진을 삭제한다면 다른 사람 모두 해당 사진을 사용할 수 없게 된다. 

 

따라서, swift 에서 class instance 를 다룰 때는 특히 주의해야 한다. 같은 instance 를 여러 변수가 참조하고 있다면 하나의 변수에서의 수정이 해당 instance 를 공유하는 모든 변수에도 영향을 주기 때문이다.

'swift' 카테고리의 다른 글

Static, Dynamic(table), 그리고 Message dispatch  (0) 2021.12.15
[Swift] Optional 이해하기  (0) 2021.06.09
ARC, weak, and weak self  (0) 2021.03.17