본문 바로가기

Swift

프로퍼티 - 저장 프로퍼티

728x90

프로퍼티 .. 가 무엇인가 하면 .. 이름을 붙여서 조금 어렵게 느껴지는 것이지 단순하게 그러니까 쉽게 말하면 우리가 지금까지 열심히 작성한 클래스/구조체에서 선언하던 상수/변수를 말한다.

 

그리고 Swift에에서 프로퍼티는 크게 3가지로 나눌 수 있다. (그 안에서 프로퍼티 앞에 붙는 키워드에 따라서 조금 다르게 분류되기도 한다.)

  1. 저장 프로퍼티
  2. 연산 프로퍼티
  3. 타입 프로퍼티 

이렇게 세개가 존재한다.

 

저장 프로퍼티 

먼저, 저장 프로퍼티에 대해서 알아보자면, 

클래스와 구조체에서만 사용할 수 있고, (이름처럼) 값을 저장하기 위해서 선언되는 상수/변수를 말한다.

 

class Human {
    let name: String = "unknown"
    var age: Int = 0
}
 
struct Person {
    let name: String = "unknown"
    var age: Int = 0
}

위와 같이 Human이라는 클래스에 대해서, Person이라는 구조체에 대해서 저장된 name, age라는 상수/변수는 모두 저장 프로퍼티에 해당한다.

 

이 때, 주의할 점은 클래스와 구조체의 차이에 있다.

구조체의 경우,

저장 프로퍼티가 옵셔널이 아니더라도, 이를 포함하는 이니셜라이저를 자동으로 생성한다. 그러나

 

클래스의 경우,

옵셔널이 아니라면, 프로퍼티 기본 값을 지정하거나 사용자 정의 이니셜라이저를 통해서 반드시 초기화를 해주어야 합니다.

 

지연 저장 프로퍼티 

이런 저장 프로퍼티 앞에 lazy라는 키워드가 붙게 되면,

지연 저장 프로퍼티가 된다.

 

지연 저장 프로퍼티란, 프로퍼티가 호출되기 전까지는 선언만 될 뿐 초기화되지 않고 있다가, 프로퍼티가 호출되는 순간에 초기화가 되는 저장 프로퍼티를 말한다.

 

즉, 해당 프로퍼티가 직접 이름이 불려서 호출이 되는 순간, 그 순간에 초기화가 이루어지는 것이다.

예시를 통해서 살펴보면 다음과 같다.

class Contacts {
   var email: String = ""
   var githubLink: String = ""
 
    init() { print("Contacts 초기화 🚨") }
}
 
class Human {
   var name: String = "unknown"
   var contacts: Contacts = .init()
}

여기서 Human이라는 클래스를 만들고 초기화를 하면 다음과 같다.

let soKyte: Human = .init()

 

클래스, 구조체 모두 인스턴스를 생성할 경우, 초기화 구문이 불리는 순간 모든 프로퍼티가 초기화가 이루어져야 한다.

그러므로 위의 soKyte라는 Human 클래스에 대한 인스턴스를 만들고 init으로 호출하면, Human 인스턴스 안에 있는 모든 프로퍼티가 초기화되면 contacts라는 프로퍼티도 초기화가 됩니다.

 

그래서 다음과 같이 print문이 나타나는 것을 확인할 수 있습니다.

 

그런데 만약 contacts란 저장 프로퍼티 앞에 lazy라는 키워드를 붙이게 되면,

class Contacts {
   var email: String = ""
   var githubLink: String = ""
 
    init() { print("Contacts 초기화 🚨") }
}
 
class Human {
   var name: String = "unknown"
   lazy var contacts: Contacts = .init()
}

그리고 다시 인스턴스를 생성하고 초기화를 한다면, 위에서 보았던 print 문이 나타나지 않는 것을 확인할 수 있습니다.

앞서 말씀드린 것과 같이 선언만 되었을 뿐, contacts라는 변수 자체가 초기화가 되지 않았기 때문입니다.

 

그리고 다시, contacts란 변수에 접근을 하게 되면 (= 이름을 불러주면)

soKyte.contacts.githubLink = "sokyte"

다시 프린트문이 나타나는 것을 확인할 수 있습니다. 

 

지연 저장 프로퍼티의 특징

lazy라는 키워드는 항상 var와 함께 사용해야 합니다.

(= lazy let으로 선언할 수 없습니다.)

그 이유는 lazy의 경우, 초기화가 늦어지는 것으로 만약 let으로 선언하게 된다면 필요한 시점에 초기화를 할 수 없기 때문입니다.

이미 메모리에 올라가 있지만, 필요한 시점에 원하는 값을 초기화가 되어야 하는데 let으로 선언한 경우 그럴 수 없기 때문이죠.

 

적재적소에 사용한다면, 성능도 향상되고 메모리 낭비도 줄일 수 있습니다. 

인스턴스를 만들 때 모든 프로퍼티가 초기화가 되어야 하는 것은 아닙니다. 때에 따라서는 나중에 해당 프로퍼티를 접근하려고 할 때 초기화가 필요한 경우도 있습니다. 특히나 많은 정보가 담겨 있는 저장 프로퍼티의 경우는 더욱 유의해야 합니다. 

그러므로, 잘 사용한다면 필요한 경우에만 초기화가 가능하기 때문에 메모리 낭비를 줄일 수 있고, 이는 성능 향상으로 이어집니다. 

 

 

+ 열거형에서는 쓰지 못하는 이유가 있을까요?

enum과 같이 열거형 안에서 저장 프로퍼티를 사용하려고 하면 다음과 같이 오류가 나타나는 것을 확인할 수 있습니다.

열거형의 경우, 저장 프로퍼티를 사용할 수 없고 연산 프로퍼티(computed property)를 사용할 수 있습니다.

'Swift' 카테고리의 다른 글

Singleton Pattern  (0) 2022.08.05
프로토콜  (0) 2022.08.02
some  (0) 2022.04.29
Any/AnyObject  (0) 2022.04.29
mutating  (0) 2022.04.29