본문 바로가기

Swift

Swift(1) - Stored Property(저장 프로퍼티)란 무엇일까?

안녕하세요! 이번에 처음 글을 쓰게 되었는데요!

항상 공부를 하다보면 알고 있다고 생각 했는데 막상 누구한테 말을 하려 하고 설명 하려고 하면 버벅거리는 경우가 많아 

확실히! 공부해보자는 생각에 블로그를 정리하면서 공부 하려고 합니다.

제가 정리하면서 공부하려는 의도로 시작하지만 혹시라도 다른분들이 보게 되신다면 책도 보고 여러 블로그도 참조하면서 하겠지만 틀린 부분이나 잘못된 부분이 있을 수 있으니 말씀해주시면 다시 공부하고 수정하도록 하겠습니다.


제가 처음으로 정리하려고 생각한 내용은 프로퍼티(property)에 관련된 내용인데요. 

 

먼저 프로퍼티를 크게 나누어 보면 저장 프로퍼티(Stored Properties), 연산 프로퍼티(Computed Properties), 타입 프로퍼티(Type Properties)로 구분이 가능합니다.

 

이번에는 먼저 저장 프로퍼티(Stored Properties)에 관하여 정리 하도록 하겠습니다.

 

저장 프로퍼티(Stored Properteis)


저장 프로퍼티

  • 인스턴스의 변수 또는 상수로 클래스 또는 구조체의 인스턴스와 연관된 값을 저장하고
  • 변수를 저장할때는 var 키워드를 사용하여 변수 저장 프로퍼티를 선언하고 let 키워드를 사용하여 상수 저장 프로퍼티를 선언합니다.
  • 저장 프로퍼티를 정의할때는 기본값을 지정할 수 있으며, 초기화 할때는 초기값을 지정할 수 있습니다.

 

 다음은 애플 공식 문서에 있는 저장 프로퍼티의 예시를 보도록 하겠습니다.

 

1. 구조체

여기서 보시면 FixedLengthRange라는 구조체 안에 변수 firstValue와 상수 length를 선언하신 것을 보실 수 있습니다. 보시면 firstValue같은 경우 변수이기 때문에 초기화된 값을 변경할 수 있지만 length는 상수로 선언되어 있어 초기화 된 값을 변경하려고 하면 오류가 뜹니다!!

 

2. 클래스

위에서는 구조체로 저장 프로퍼티를 사용했다면 이번에는 class에서 저장 프로퍼티를 사용해 보려고 하는데요. 클래스 같은 경우에는 초기값이 없다면 이니셜라이저로 따로 정의해야 합니다(이는 구조체는 자동으로 이니셜라이저를 생성하지만 클래스는 아니기 때문입니다). 따라서 init을 사용하여 이니셜라이저를 만들어주기로 합니다!

여기서도 보시면, length 같은 경우에는 상수 이기 때문에 값을 변경하려고 하면 오류가 뜨는 것을 확인할 수 있습니다.

 

그렇다면 제가 왜 굳이 구조체와 클래스를 나눠서 해보았을까요?

FixedLengthRange를 구조체와 클래스로 구분하여서 똑같이 선언해주었습니다. 

똑같이 mino를 let으로 선언하였지만 구조체는 오류가 뜨고 클래스는 오류가 뜨지 않는 것을 확인할 수 있습니다.

왜냐하면! 이는 구조체는 값 타입 이고 클래스는 참조 타입이기 때문인데요. 클래스는 참조 타입이므로 원본에 접근이 가능하여 값을 바꿀 수 있는 겁니다.

 

저장 프로퍼티를 선언하다 보니 클래스와 구조체의 차이까지 말하게 되었는데요. 

클래스와 구조체의 차이는 중요한 만큼 정리해서 블로그에 올리고 태그를 걸도록 하겠습니다!

 

저장 프로퍼티에 대해 간단하게 마지막으로 정리하자면 저장 프로퍼티는 객체의 속성을 저장한다고 할 수 있습니다!

저장 프로퍼티의 종류는 하나 더 있는데요 이번에는 지연 저장 프로퍼티(Lazy stored properties)에 대해서 설명 하도록 하겠습니다.

 

지연 저장 프로퍼티(Lazy stored properties)


지연 저장 프로퍼티에 관한 애플 공식 문서를 보면

이 말을 해석해 보면 지연 저장 프로퍼티는 이것이 처음 사용되기 전까지는 초기값이 계산되지 않으며 저장 프로퍼티 앞에 lazy 키워드를 붙여 선언한다는 것을 알 수 있습니다.

 

  • lazy 즉, 게으른이라는 뜻을 가진 지연 저장 프로퍼티는 값의 호출이 있어야만 값을 초기화 합니다.
  • 이때의 포인트는! 지연 저장 프로퍼티의 경우 필요할때 값을 할당하기 때문에 상수로 선언이 불가하여 var 즉, 변수로만 선언이 가능합니다.
  • 지연 저장 프로퍼티는 주로 복잡한 클래스나 구조체를 구현할때 많이 사용하게 됩니다. 예를 들어 클래스 인스턴스의 저장 프로퍼티로 다른 클래스 인스턴스를 할당해야 하는 경우 인스턴스를 초기화하면서 저장 프로퍼티로 쓰이는 인스턴스들이 한 번에 생성 되어야 할때, 혹은 모든 저장 프로퍼티를 사용할 필요가 없을때는 저장 프로퍼티를 사용하는 것이 좋습니다.
  • 지연 저장 프로퍼티를 잘 사용한다면 불필요한 공간 낭비를 줄일 수 있습니다!

 

이번에는 야곰님께서 쓰신 책으로 예제를 보도록 하겠습니다.

struct CoordinatePoint {
  var x: Int = 0
  var y: Int = 0
}

class Positon {
  lazy var point: CoordinatePoint = CoordinatePoint()
  let name: String
  
  init(name: String) {
    self.name = name
  }
}

let yagomPosition: Position = Position(name: "yagom")

// 이 코드를 작성하면 point 프로퍼티에 처음 접근할 때 point 프로퍼티의 CoordinatePoint가 생성됩니다!
print(yagomPosition.point)
  • 설명 드리자면 그 전까지는 CoordinatePoint가 생성되지 않다고 point에 접근 할때 생성된다는 의미입니다!!

 

이렇게 지연 저장 프로퍼티에 대해 공부하다 보니 이런 의문이 생겼습니다. 

그렇다면 사용전까지 인스턴스가 생성되지 않으니 모든 변수는 지연 저장 프로퍼티로 선언하는 것이 혹시 모를 메모리 낭비를 줄일 수 있으니 좋지 않나????

 

하지만 지연 저장 프로퍼티도 유의해야 하는 점이 있는데요 

 : 다중 스레드 환경에서 지연 저장 프로퍼티에 동시다발적으로 접근하게 되면 한번만 초기화 된다는 보장이 없을 수도 있으며 생성되지 않은 지연 저장 프로퍼티에 많은 스레드가 비슷한 시점에 접근한다면 여러번 초기화 될 수도 있다고 합니다.

 

따라서 상황에 맞게 지연 저장 프로퍼티를 사용하는 것이 좋을 것 같습니다!


오늘은.. 여기까지..