[Swift iOS] 프로퍼티(Properties)에 대해서

JB
6 min readOct 12, 2020

--

프로퍼티(Properties)란 클래스나 구조체 또는 열거형에 값을 할당합니다.

저장 프로퍼티(Stored properties)는 상수나 변수를 인스턴스의 한 부분에 저장을 하는 반면, 연산 프로퍼티(Computed properties)는 저장을 하기보다는 계산(calculate)을 하는 역할을 합니다.

저장 프로퍼티는 클래스나 구조체에서만 제공되는 반면 연산 프로퍼티는 클래스, 구조체, 열거형에서 제공됩니다.

또한, 저장프로퍼티나 연산프로퍼티는 특정 타입의 인스턴스와 함께 할당됩니다. 그러나, 타입 프로퍼티(type properties)와 같은 특정 프로퍼티들은 자신의 타입(type itself)로만 할당이 가능합니다.

또한 프로퍼티의 값이 변경되는 것을 관찰할 수 있는 프로퍼티 옵저버(property observer)를 정의할 수 있습니다.

마지막으로 프로퍼티 래퍼(property wrapper)를 사용해서 여러개의 프로퍼티의 getter와 setter를 재사용 할 수 있습니다.

저장 프로퍼티 (Stored Properties)

저장 프로퍼티는 그 이름 그대로 변수나 상수를 클래스나 구조체의 인스턴스의 한 부분으로 저장 하는 것을 말합니다.

저장 프로퍼티는 에는 변수 저장 프로퍼티(variable stored properties)라고 불리는 var 키워드를 사용하여 저장을 하는 프로퍼티, 상수 저장 프로퍼티(constant stored properties)라고 불리는 let키워드를 사용하여 사용하는 프로퍼티가 있습니다

저장프로퍼티 (Stored Properties)의 예

engthRange 인스턴스는 firsValue length 라는 저장 프로퍼티를 가지고있습니다.

length 의값은 새로운 Range가 생성될 때 초기화 되었고 length 라는 저장 프로퍼티는 상수 타입이기 때문에 최초 이니셜라이즈 후에 값이 변할 수 없습니다.

지연 저장 프로퍼티 ( Lazy Stored Properties)

지연 저장 프로퍼티는 처음으로 그 값이 사용되기 전가지 최초 값이 곗나되지 않는 프로퍼티를 말합니다. lazy 를 사용함으로써 이는 지연 저장 프로퍼티(lazy stored property) 라는 걸 나타냅니다.

최초 값이 인스턴스 초기화가 끝날때 까지 갖을 수 없기때문에 지연 저장 프로퍼티는 항상 변수(var 키워드)를 사용해 줘야 합니다. 상수 프로퍼티들은 초기화가 끝나기 전에 값이 있어야하기 때문에 지연(lazy)로 선언 될 수 없습니다.

지연 프로퍼티는 인스턴스의 초기화가 끝날시점까지 외부 요소의 값을 알 수 없을 때, 하지만 초기값이 이 외부 요소의 값과 의존적일때 유용합니다.

또한 이 프로퍼티의 초기값이 필요해질때까지 실행을 하지 않거나 굉장히 복잡한 연산을 할때도 지연 프로퍼티를 유용하게 사용할 수 있습니다.

지연 저장 프로퍼티의 사용

DataImporter 라는 클래스가 생성되어 초기화 되었을 때 DataManager 라는 클래스는 그 때 file을 읽어와 그 데이터를 관리할 수 있습니다.

지연된 importer 객체가 생성 될 때

importer 객체 생성 시
만약 프로퍼티가 lazy 로 선언되었지만 다중 스레드에서 동시다발적으로 접근이 되었고 그 프로퍼티가 아직 초기화가 되지 않았다면, 그 프로퍼티는 한번만 초기화 되었다는 것을 장담할 수 없습니다.

이 지연 프로퍼티를 사용하면 인스턴스의 초기화 시 불필요한 모든 저장프로퍼티를 초기화 하지 않아도 됩니다. 그러므로, 불필요한 메모리 낭비를 방지할 수 있습니다.

연산 프로퍼티 (Computed Properties)

저장 프로퍼티 이외에, 클래스, 구조체, 열거형에서는 연산 프로퍼티를 정의할 수 있습니다. 연산 프로퍼티는

  • 값을 저장하지 않고 계산을 하는 역할
  • getter를 제공
  • optional setter를 제공

과 같은 특징이 있습니다.

연산 프로퍼티(Computed Properties)의 예

Rect 구조체에서의 getter와 setter는 연산 프로퍼티의 역할을 수행하고있습니다.

getter setter 축약형

Rect 구조체의 getter and setter는 위와같이 축약형으로도 표현이 가능합니다.

읽기전용 연산 프로퍼티 (Read-Only Computed Properties)

연산 프로퍼티에서 getter만 있고 setter가 없는 프로퍼티를 읽기전용 연산 프로퍼티 (Read-Only Computed Properties) 라고 합니다.

이는

  • 항상 값을 리턴 (always return a value)
  • .형식 (dot syntax)를 통해 접근이 가능
  • 새로운 값을 세팅 불가
읽기전용 연산 프로퍼티 (Read-Only Computed Properties)의 예

volume이라는 연산 프로퍼티가 있습니다. volume 변수는
1. 항상 값을 리턴하고,
2. 인스턴스화된 fourByFiveByTwo의 . 을 통해 접근이 가능하고
3. 새로운 값을 세팅하려 fourByFiveByTwo.volume으로 접근하려했지만 접근이 불가하였습니다.

프로퍼티 감시자 (Property Observers)

프로퍼티 감시자는 프로퍼티의 값을 관찰하고 이에 대한 응답을 합니다. 프로퍼티의 값이 세팅 될때마다 프로퍼티 감시자들은 불리며, 심지어 바뀐값이 현재의 값과 같다고 해도 불리게 됩니다.

  • 저장 프로퍼티
  • 상속된 저장 프로퍼티
  • 상속된 연산 프로퍼티

에서 프로퍼티 감시자를 사용 가능합니다.

상속된 프로퍼티들은 서브클라스된 프로퍼티에 오버라이딩 함 으로써 프로퍼티 감시자를 사용 할 수 있습니다.

프로퍼티 감시자에는 2가지 종류가 있습니다:

  • willSet 은 값이 저장되기 바로 직전에 불림
  • didSet은 값이 저장되고 그 즉시 불림
프로퍼티 감시자(Property Observers)의 예

위 예제를 보면 willSettotalSteps값이 세팅되기 직전에 호출, didSettotalSteps값이 새로 세팅이 되고 난 후에 호출이 되는 것을 확인 할 수 있습니다.

프로퍼티 래퍼(Property Wrappers)

프로퍼티 래퍼는 프로퍼티가 저장되는 코드와 프로퍼티를 정의하는 코드 사이에 계층을 나눕니다.

프로퍼티 래퍼는

  • 프로퍼티 래퍼를 정의할때마다 관리 코드를 작성
  • 그 관리 코드를 여러 프로퍼티에 적용할때 재사용
  • 클래스, 구조체, 열거형에서 wrappedValue 프로퍼티 정의
프로퍼티 래퍼 (Property Wrapper) 예
propertyWrapper는 먼저 클래스, 구조체, 열거형 선언 앞에 @propertyWrapper 라고 정의해줍니다.

TwelveOrLess라는 구조체에 wrappedValue라는 변수 프로퍼티를 설정해주고, set값으로 12이하가 되게끔 설정해 줍니다.

이후, SmallRectangle이라는 구조체의 height와 width의 최초 프로퍼티 값 설정을TwelveOrLess를 정의할 때의 최초 값으로 설정해 줍니다.

SmallRectangle의 인스턴스화 이후 값을 22로 설정해 주지만 값은 12가 찍힙니다. 이는 Property Wrapper의 설정을 따르기 때문에 최대값인 12까지밖에 찍힐 수가 없는 것 입니다.

--

--

JB
JB

Written by JB

iOS engineer @kakaobank

No responses yet