티스토리 뷰

다마고치를 키우는 앱을 만들다가 모델을 struct에서 class로 변경하였는데 didSet이 되지 않는 현상이 생김

단지 struct에서 class로 변경한 것 뿐 모든게 동일했는데 왜 안되는 걸까

 

일단 코드를 살펴보면

struct TamaStruct {
    let name = "TAMATAMA"
    var rice = 0
    var water = 0
}

class TamaClass {
    let name = "TAMATAMA"
    var rice = 0
    var water = 0
}

var tamaStruct = TamaStruct(){
    didSet {
        print("tamaStruct 변경됨")
    }
}

var tamaClass = TamaClass(){
    didSet {
        print("tamaClass됨 변경됨")
    }
}

tamaStruct.rice += 1
tamaClass.rice += 1

tamaClass 인스턴스의 rice와 tamaStruct인스턴스의 rice를 1씩 증가시켰음

여기서 예상한 결과 값은 둘 다 didSet안의 print가 호출되는 거였음.

tamaStruct 변경됨

 근데 출력은 struct만 됨.. 여기서 class는 didSet이 동작하지 않는건가?라는 일차적인 생각을 하게 됨

tamaClass = TamaClass()
tamaStruct = TamaStruct()

// tamaClass 변경됨
// tamaStruct 변경됨

tamaClass 자체를 바꿔주면 또 동작함. 구조체 인스턴스도 자체를 바꿔주면 동작함

여기서 일단 다른 궁금한 점이 생김.

처음 생성할 때도 set되는건데 didSet 왜 안되나요?

didSet은 초기화 이후에만 불림. 그니까 처음에 만들어도 호출되지 않고 그 이후 뭔가 값이 변동되면 호출됨

다시 돌아가서 class의 경우 왜 안되는지 생각해보도록 함. 이해를 위해 그림을 그려보았음.

class는 참조타입이고 힙에 저장됨

이 참조타입의 인스턴스는 객체 원본의 주소값만 알고 있고 그 외의 정보는 모름

그렇다면 TamaClass의 rice가 변경되더라도 인스턴스는 해당정보를 알 수가 없고

TamaClass 자체에 변화가 있어야 동작함    

 

struct는 값타입이고 스택에 저장됨

이 값타입의 인스턴스는 그 객체 자체의 정보를 갖고 있음. tamaStruct는 TamaStruct의 모든 정보를 갖고 있는 것임

그렇기 때문에 변화를 감지할 수 있음

또 참조타입은 제자리에서 변할 수 없어서 변수의 변경이 곧 인스턴스의 변경이 됨

그렇기 때문에 tamaStruct 자체에 didSet이 되어있어도 변수가 변경될 때 변화를 감지할 수 있음

 

최근에 올라온 글
Total
Today
Yesterday