본문 바로가기

iOS/Swift

Swift) 프로퍼티 정복하기 (3/4) - 타입 프로퍼티(Type Property)

 

 

 

안녕하세요 :) 소들입니다!!!

휴~~~ 먼저 오랜만이란 말을 하고 싶네요...!!

실로 포스팅이 오랜만이기도 하고,,, 한 5일간 저에겐 많은 사건이 있었거든요...하하;;

 

제가 식중독에 걸렸었어요 흑흑 상한 걸 잘못 주워먹어갖고

열이 높아 진료도 못보고 코로나 검사 하고.. 흑흑 음성 뜨고 나서야 수액 맞고 살아났어요

근데 코로나 검사 아프다해서 겁 먹었는데 하나도 안 아프던데요..? (우리 보건소 최고)

 

그래서 뭐 어쩌라고 싶겠지만,

그냥 너무 아픈 순간에도 마지막으로 쥐어짠 포스팅이 연산 프로퍼티 포스팅이라서...

제 포스팅 중에 가장 기억에 남는? 눈물로 쓴 포스팅이 될 것 같아요 ..하하 :) 

걍 이 글을 읽는 모~든 분들 음식 조심하시고, 건강이 최고입니다🌚

 

자, 우리가 이전에 저장 프로퍼티와 연산 프로퍼티를 공부 했으니!

그럼 마지막으로 타입 프로퍼티를 공부하러 고고 씽 해봅시다~~~

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. 타입 프로퍼티(Type Property)란?

 

클래스, 구조체, 열거형에서 사용된다

저장 타입 프로퍼티와 연산 타입 프로퍼티가 존재하며,

저장 타입 프로퍼티의 경우 선언할 당시 원하는 값으로 항상 초기화가 되어 있어야 한다

"static"을 이용해 선언하며, 자동으로 lazy로 작동한다(lazy를 직접 붙일 필요 또한 없다)

 

흐음....  정의는 늘 어렵지만 이번엔 더 어려운 것 같네 하핳하

아니 저장 프로퍼티와 연산 프로퍼티는 저번 포스팅에서 공부해서 알겠는데, 

저장 "타입" 프로퍼티와 연산 "타입" 프로퍼티는 뭥미!?! 싶겠지만..

 

쉽게 말하면, 저장&연산 프로퍼티 앞에 "static"이란 키워드만 붙이면

그것은 저장 타입 프로퍼티 & 연산 타입 프로퍼티가 되는 것임

(물론 나중에 연산 타입 프로퍼티에서 사용하는 class 키워드도 공부할 것임)

 

 

class Human {
    let name: String = "sodeul"     // 저장 프로퍼티
    var alias: String {             // 연산 프로퍼티
        return name + "은 바보"
    }
}
 

 

 

이렇게 평범하게 생긴 저장 프로퍼티와 연산 프로퍼티 앞에다가 static을 뙇 붙이면

 

 

class Human {
    static let name: String = "sodeul"     // 저장 타입 프로퍼티
    static var alias: String {             // 연산 타입 프로퍼티
        return name + "은 바보"
    }
}
 

 

 

저장 타입 프로퍼티연산 타입 프로퍼티가 되는 것임

또한 위에서 정의에서 저장 타입 프로퍼티의 경우, 항상 초기값을 가져야 한다고 했음

위에선 name이란 저장 타입 프로퍼티가 "sodeul"이란 값으로 초기화 되어 이씅니 문제는 없다만,

 

근ㄷㅔ 만약 선언과 동시에 저장 타입 프로퍼티를 초기화 안 해주면? ㅇㅓ케될까?

 

 

 

 

static으로 선언할 경우, initializer가 필수거나 getter/setter를 지정해야 한다는 오류가 뜸

 

이게 먼말이냐??

너 저장 타입 프로퍼티 선언하고 싶으면 초기 값 지정 하든가! 아니면 연산 타입 프로퍼티로 만들든가!

 하고 에러 뱉는 것임

 

그 이유는, static으로 선언되는 저장 타입 프로퍼티의 경우 초기화할 때

값을 할당할 initializer가 없기 때문

 

오잉??

name은 타입 프로퍼티로 선언되어 있긴 하지만, Human이란 클래스 안에 있구

Human 클래스의 인스턴스가 생성될 때 initializer에 의해 모든 프로퍼티가 초기화 되지 않나용!?

 

이란 의문을 가질 수 있는데,

타입 프로퍼티는 인스턴스가 생성될 때마다 "매번 생성"되는 "기존 프로퍼티"와 다름!!!!

인스턴스가 생성 된다고 매번 해당 인스턴스의 멤버로 매번 생성되는 것이 아니라,

 

언제 한번 누군가 한번 불러서 메모리에 올라가면, 그 뒤로는 생성되지 않으며

언제 어디서든~ 이 타입 프로퍼티에 접근할 수 있는 것임

 

전역 변수로 생각하면 조금 더 편할 것 같음!!!

 

 

 

 

당연히, 인스턴스 생성할 때마다 각자 가지는 프로퍼티가 아니기 때문에

sodeul이란 Human 인스턴스를 생성했지만, 그 안엔 저장 타입 프로퍼티인 name이 없음!!

 

 

그럼 타입 프로퍼티인 name엔 어떻게 접근 하느냐??

 

 

 

 

 

이렇게, 타입 이름을 통해서만 접근 가능함!!!!

 

자, 이제 왜 저장 타입 프로퍼티가 무조건 초기값을 가져야 하는지에 대해 답이 나왔음!

 

인스턴스가 생성된다고 타입 프로퍼티가 매번 생성되는 것이 아니라,

타입 프로퍼티는 누군가 나를 불러줬을 때 한번 메모리에 올라가고,

그 뒤로는 어디서든 해당 프로퍼티를 "공유" 하는 형태

 

따라서 인스턴스 생성과 전~~혀 상관이 없기 때문에

인스턴스 생성 시 불리는 initializer 또한 상관 없는 내용이고!!

따라서 초기값이 없을 경우, 초기 값을 셋팅할 방법이 없기 때문에 반드시 초기값을 지녀야 한다!!!

 

그로하다........:D

자, 근데 위에서 자꾸 타입 프로퍼티의 경우

 

"누군가 나를 불러줬을 때 메모리에 올라간다"

 

라는 말을 하는데, 이 말은 머 저장 프로퍼티의 속성인 lazy와 동일한 말임!!

정의에서 설명했듯이, 타입 프로퍼티의 경우 기존 속성이 lazy이기 때문에

name이란 프로퍼티를 최초 호출하기 전까진, 초기화되지 않음!!!!

 

근데, 다음과 같이 name이란 타입 프로퍼티를 최초 호출 하면,

 

 

Human.name

 

 

이때! 메모리에 올라가서 초기화 되는 것임 :)

 

흠...... 근데 지연 저장 프로퍼티의 경우 항상 var로 선언해야 했잖음??...

근데 static은 기본이 lazy 동작인데,,, let/var 저장 프로퍼티로 선언해도 문제가 없네..?ㅠ;;

--> 이 부분에 대해선 댓글로 설명 추가 했습니다!

 

 

 

 

2. 타입 프로퍼티의 접근

 

위에서 이미 설명 했지만, 타입 프로퍼티의 경우

타입 자체의 이름.(dot) 문법을 통해 접근함

 

 

class Human {
    static var name = "Sodeul"
    static let age = 100
}
 
Human.name                  // "Sodeul"
Human.name = "Unknown"
Human.name                  // "Unknown"
 
Human.age = 200             // error!! 상수 변경 불가

 

 

이렇게!!!! var로 선언된 타입 프로퍼티의 경우, 당연히 수정도 가능함!!!

 

 

 

 

3. 연산 타입 프로퍼티의 오버라이딩

 

타입 프로퍼티 하다가 갑자기 오버라이딩이 나와서 당황 했겠지만

하하,,, 사실 "연산 타입 프로퍼티"는 Subclass에서 오버라이딩이 가능함!

다만, 앞에 class를 붙여주나 static으로 붙여주냐의 차이임!!!!

 

 

 

3-1. class : 오버라이딩이 가능한 "연산 타입 프로퍼티"

 

 

class Human {
    class var alias: String {
        return "Human Type Property"
    }
}
 
class Sodeul: Human {
    override class var alias: String {
        return "Sodeul Type Property"
    }
}
 
Human.alias             // "Human Type Property"
Sodeul.alias            // "Sodeul Type Property"

 

 

이렇게 class로 선언한 연산 프로퍼티의 경우,

static 선언과 마찬가지로 "연산 타입 프로퍼티"임!!!!

다만, Subclass에서 위처럼 연산 타입 프로퍼티를 오버라이딩 해서 쓸 수 있음!!!

 

 

 

3-2. static : 오버라이딩이 "불"가능한 "연산 타입 프로퍼티"

 

 

class Human {
    static var alias: String {
        return "Human Type Property"
    }
}
 
class Sodeul: Human {
    override static var alias: String {     // error! Cannot override static property
        return "Sodeul Type Property"
    }
}
 

 

 

위에서 공부한 static으로 선언한 경우,

static property는 오버라이딩이 불가능하다며 에러가 남 :)

 

 

 

 

4. 타입 프로퍼티는 왜 쓸까?

 

보통 모든 타입이 공통적인 값을 정의하는 데 유용하게 쓰임!!!

가장 대표적인 것(?)이 싱글톤인데, 싱글톤이 뭔지 모르면 이 포스팅을 보시길

 

 

 

 

 

 

 

 

 

 

.

.

.

음......프로퍼티의 포스팅도 점차 끝이 보여 가는데....;;;;

아플 때 썼던 포스팅보다 퀄리티나 내용이 더 맘에 안든다ㅠㅠㅠㅠㅠㅠㅠ

만약 이해가 더 필요하단 분이 있으시면 제가 그래왔듯이 그림을 넣든 

메모리사진을 넣든 해서 더 보강하도록 하겠숩ㅂ니다...

 

읽어주셔서 감사합니다 :)

잘못된 내용 & 피드백 & 궁금증은 언제나 댓글 주세요!!!!



Calendar
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
최근 댓글
Visits
Today
Yesterday