본문 바로가기

iOS/Swift

Swift) 프로퍼티 정복하기 (2/4) - 연산 프로퍼티(Computed Property)

 

 

 

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

저번 포스팅에서 프로퍼티의 종류엔 3가지가 있고,

그중 저장 프로퍼티에 대해 공부 했어요!!! 모른다면 이 포스팅 참조

 

이번에 공부할 내용은 연산 프로퍼티라는 것이에요!

코드를 보다보면 프로퍼티 생김새가 신기하게 생겨갖고

get, set 뭐 이딴거 써있는 거 있거등여 그거 공부할 것임

 

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

 

 

 

 

1. 연산 프로퍼티(Computed Property)란?

 

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

 저장 프로퍼티와 달리 저장 공간을 갖지 않고,

다른 "저장 프로퍼티"의 값을 읽어 연산을 실행하거나, 프로퍼티로 전달받은 값을 다른 프로퍼티에 저장한다

때문에 항상 var로 선언되어야 한다

 

음... 뭐 정의는 이런데.......

늘 그렇듯 정의만 보면 뭔말인지 1도 모르고요

일단 여기서 짚고 넘어갈 것은!!!

 

저장 프로퍼티는 열거형에서 사용 못했는데, 연산 프로퍼티는 되네?!

연산 프로퍼티는 직접 값을 "가지지는(저장하진) 않고", "다른 저장 프로퍼티"를 지지고 볶고 하는 건가 보네??

 

여기까지만 이해하면 사실 끝임 하하하하하하

자, 먼저 연산 프로퍼티의 생김새는 어떻게 생겼냐면

 

 

var nameType {
    get {           //getter (다른 저장 연산프로퍼티의 값을 얻거나 연산하여 리턴할 때 사용)
        statements
        return expr
    }
    set(name) {     //setter (다른 저장프로퍼티에 값을 저장할 때 사용)
        statements
    }
}
 

 

 

자 이렇게 생겼음!!!!!!!!!!1

get을 getter, set을 setter라 부름!!!(포스팅에선 섞어쓰겠음)

 

먼저,

연산 프로퍼티는 어떠한 값을 저장하는 것이 아니기 때문에,

타입 추론을 통해 형식을 알 수 없어서, 반드시 선언할 때 타입 어노테이션을 통해 자료형을 명시해야 함!!!

그리고 선언된 자료형 뒤에 {} 를 붙이는 것이 연산 프로퍼티의 사용법임

 

따라서, 내가 어떤 타입의 값을 받아서 다른 저장 프로퍼티에 저장할 것인지,

어떤 타입의 값을 리턴할 것인지를 명시해주어야 함!!!

 

getter는 말 그대로 "얻는" 것임!

따라서 어떤 저장 프로퍼티의 값을 연산해서 return할 것인지, return 구문이 항상 존재해야 함

 

setter는 말 그대로 "설정"하는 것임!

따라서 파라미터로 받은 값어떤 저장 프로퍼티에 어떻게 설정할 것인지를 구현함!!

 

흠.... 여기까지도 아리송 할거 같음!!! 더 좋은 이해를 위해 예제를 보자 :)

자, 만약 다음과 같은 Person이란 클래스가 있음

 

 

class Person {
    var alias: String {
        get {
            return alias
        }
        set(name) {
            self.alias = name
        }
    }
}

 

 

오 alias란 프로퍼티는 신기하게 생겼네??

근데 Type Annotation 뒤에 {}가 시작되고, 그 안에 get과 set이 있네???

아하! alias는 연산 프로퍼티이구나!!

 

이렇게 생각할 수 있는 것까진 좋음!!

근데 위 코드는 잘못된 코드임!!!!! 왜냐???

 

연산 프로퍼티는 다른 "저장 프로퍼티"를 지지고 볶고 하는 놈이라 했음!!!

근데 위 코드는 get, set에서 alias란 "연산 프로퍼티"를 지지고 볶고 있음

 

따라서, 엄청난 오류 메세지가 발생하고,

 

 

 

 

실제 런타임까지 가면,

getter가 무한으로 호출되는 무한 재귀 함수에 빠져버려용

 

따라서, 연산 프로퍼티를 사용하려면 무조건

 

 

class Person {
    var name: String = "Sodeul"
 
    var alias: String {
        get {
            return name
        }
        set(name) {
            self.name = name
        }
    }
}

 

 

name과 같이 읽거나 쓸 수 있는 "저장 프로퍼티"가 먼저 존재해야 하고,

연산 프로퍼티에선 이 다른 "저장 프로퍼티"의 값을 읽거나 쓰는 작업을 해야 함!!!!

 

물론 위처럼 단순하게

name이란 저장 프로퍼티의 값을 읽어서 return하는 get,

파라미터로 받은 값을 그대로 name이란 저장 프로퍼티에 값을 저장하는 set

처럼 구현해도 되지만, 뭐 원한다면 다음과 같이 다른 연산 작업들을 직접 해줄 수도 있음!!!

 

 

class Person {
    var name: String = "Sodeul"
 
    var alias: String {
        get {
            return self.name + " 바보"
        }
        set(name) {
            self.name = name + "은 별명에서 지어진 이름"
        }
    }
}
 

 

 

이런 식으로 원하는 연산을 해서 getter를 작성할 수도,

파라미터로 받은 값을 원하는 연산을 해서 setter를 작성할 수도 있음!!!

 

아 그럼 연산 프로퍼티인 alias는 어떻게 쓰는 건데염;;;

 

 

 

1-1. 연산 프로퍼티의 사용 방법

 

ㅇㅖ.. 다를 거 없고 그냥

우리가 아무렇지 않게 사용하던 저장 프로퍼티처럼 사용하면 됨!!!!!!!!1

 

 

let sodeul: Person = .init()
 
// get에 접근
print(sodeul.alias)             // Sodeul 바보
 
// set에 접근
sodeul.alias = "소들"
print(sodeul.name)              // 소들은 별명에서 지어진 이름

 

 

이런 식으로 마치 저장 프로퍼티에 접근하는 마냥

 

연산 프로퍼티인 alias값을 읽으면, alias의 getter가 실행되어 "Sodeul 바보" 라는 값이 나온 것이고,

연산 프로퍼티인 alias에 값을 쓰면, "소들"이란 값이 setter의 파라미터로 넘어가 set 함수가 실행

 

이제 연산 프로퍼티에 대해 감이 왔기를!!! :)

 

 

 

1-2. newValue : set의 파라미터는 생략이 가능하다!

 

음 set 생략 전에 set에 대해 좀 더 짚고 넘어가자면,

 

✔️ set은 파라미터를 받을 때 왜 타입을 명시해주지 않음?

이라는 의문을 품을 수 있음

 

 

 

심지어 아예 자동완성도 안해줌! 이거에 대한 답은

이미 연산 프로퍼티를 선언할 때 alias의 타입을 "반드시" 명시 해줬기 떄문

 

따라서 set으로 들어오는 저 name이란 파라미터는 반드시 명시된 String형일테니까,

따로 지정할 수 없는 것임!!!! 지정하면 타입에 민감한 스위프트에선 매우 클나니까..

 

 

아, 그리고 또 혹시 몰라 말하지만...

 

✔️set의 파라미터는 단 하나만 존재하고,

파라미터이름은 name 말고 알아서 지으시면 됨니당..ㅎㅎ;;

 

 

set(wow) {
     self.name = wow + "은 별명에서 지어진 이름"
}
 

 

 

이렇게...! wow로 지을수도 있음....!

 

자, 이제 본론으로 돌아가서!!!! 

여러분 프로그래밍 할 때 제일 힘든 게 먼줄 아셈?

그것은 바로 변 수 명 짓 기........

따라서 Swift는 매우 친절한 언어이기 때문에

 

✔️  set의 파라미터 이름 짓기 힘드신 분은 걍

get처럼 파라미터 받는 부분을 다 날려버려도 됨!!!!!!

 

그럼 파라미터를 뭘로 접근하냐?????/

 newValue 라는 이름으로 접근하면 됨!!!!!!!!!!

 

 

set {
    self.name = newValue + "은 별명에서 지어진 이름"
}
 

 

 

이렇게!!!ㅎㅎㅎ 아이 깔끔하다~~~~~~

(newvalue안됨, Newvalue안됨, 무조건 이미 정의된 이름인 newValue만 가능함)

 

 

 

1-3. get-only

 

연산 프로퍼티를 쓸 때 setter가 필요 없다면, getter만 선언해 줄 수 있음!!

이것을 get-only라고 함! 값을 읽기만 하니까

 

 

class Person {
    var name: String = "Sodeul"
 
    var alias: String {
        get {
            return self.name + "은 별명에서 지어진 이름"
        }
    }
}
 

 

 

이렇게 get만 써도 되는데,

이런 경우엔 더 간편하게 get 구문 자체를 없애서

 

 

class Person {
    var name: String = "Sodeul"
 
    var alias: String {
       return self.name + "은 별명에서 지어진 이름"
    }
}
 

 

 

이렇게 더 간단하게 쓸 수 있음!!

당연히 alias는 set이 없기 때문에 다음과 같이 연산 프로퍼티인 alias에 값을 넣으려고 하면,

 

 

 

 

get-only라서 alias에 값을 할당할 수 없다는 에러 뜸!!!

 

 

 

1-4. set-only

 

결론부터 말하자면 안 됨

 

 

 

반드시 getter를 지녀야 한다고 에러 뜸!!!

따라서 무조건 get, set을 같이 구현 하거나,  get-only로만 구현해야 함!

 

 

 

 

 

 

 

 

.

.

.

 

오늘은 프로퍼티 중에서도 연산 프로퍼티에 대해서 알아봤어요!!!!

사람인지라 틀린 내용이 있다면 언제든 피드백 주시구!!!!

궁금한 점 또한 댓글 주시면 감사하겠습니다!!

그럼 20,000

 

 

 



Calendar
«   2024/04   »
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
최근 댓글
Visits
Today
Yesterday