프로퍼티 래퍼
- 메모리가 많이 차지하는 대신에, 위험성을 줄인다는 말??
- Swift 5.1부터 나온 프로퍼티 래퍼는 클래스와 구조체 구현부에 게터, 세터, 연산 프로퍼티 코드의 중복을 줄이는 방법을 제공한다.(some이란 거랑 같이, 상당히 최근에 나온 개념임. some은 몰라도 됨!)
- 우리 수준에서는, 그냥 이게 뭔지 알면 좋지, 막 알아야 되는거는 아니다. - 나중에 현업에서 효율적이게 쓸 수 있음. 아 그냥 하면 좋은거네..ㅋㅋㅋ
- 심플하게 얘기해서, 프로퍼티 마다 get, set이 중복되는데, 그냥 변수 만들 때 변수 앞에다가 뭐 붙이자!! 라는 개념임
프로퍼티 래퍼 이해하기
- 클래스나 구조체 인스턴스에 있는 프로퍼티에 값을 할당하거나 접근할 때 저장하거나 읽어내기 전에 변환하거나 유효성 검사를 해야 할 경우가 종종 있다.
- 이 작업은 연산 프로퍼티를 만들어서 구현할 수 있다.
- 그런데, 여러 클래스나 구조체에 생성한 연산 프로퍼티들이 유사한 패턴을 갖는 경우가 빈번하게 발생한다.
- Swift 5.1이전에는 연산 프로퍼티 로직을 공유하는 유일한 방법이 해당 코드를 복사하여 각각의 클래스 구현부나 구조체 구현부에 포함시키는 것뿐이었다.
- 이것은 매우 비효율적일 뿐만 아니라, 계산 방법이 수정되는 일이 생기면 각각 클래스나 구조체에 복사해둔 연산 프로퍼티를 일일이 찾아 직접 수정해야 했다.
- 이러한 단점을 개선하기 위해서 프로퍼티 래퍼 라는 기능을 도입하였다.
- 프로퍼티 래퍼는 기본적으로 연산 프로퍼티 기능을 개별 클래스와 구조체와 분리할 수 있게 하며, 앱 코드에서 재사용할 수 있게 한다.
import Foundation
@propertyWrapper
struct FixCase{
private(set) var city: String = ""
var wrappedValue: String{
get{city}
set{city = newValue.uppercased()}
}
init(wrappedValue initialValue: String){
self.wrappedValue = initialValue
}
}
- @propertyWrapper지시자를 이용하여 선언된다. 골뱅이(@)는 어노테이션, 즉 지지자 라고 불린다.
- 모든 프로퍼티 래퍼는 값을 변경하거나 유효성을 검사하는 게터와 세터 코드가 포함된 wrappedValue프로퍼티를 가져야 한다.
- 그럼 이제 이런식으로 선언할 수 있다.
struct Contact{
@FixCase var name: String
@FixCase var city: String
@FixCase var country: String
}
여러 변수와 타입 지원하기
- 앞의 예제에서 프로퍼티 래퍼는 래핑되는 프로퍼티에 할당되는 값의 형태로 단 하나의 값을 받았다.
- 어떤 작업을 수행할 때 사용될 여러 값을 받도록 더 복잡한 프로퍼티 래퍼를 구현할 수도 있다.
- 추가되는 값들은 프로퍼티 래퍼 이름 다음의 괄호 안에 둔다.
- 지정된 값으로 사용하도록 설계된 프로퍼티 래퍼는 다음의 형태와 같다.
struct Demo{
@MinMaxVal(min: 10, max: 150) var value: Int = 100
}
- 만약 새로운 값이 들어오면 저 범위 값으로 설정해주기도 함!
- 현재 구현된건 Int로만 처리했지만, 모든 변수 타입과 함께 사용할 수 있다면 더 유용하게 될 것이다.
- 다행히도 프로퍼티 래퍼는 특정 프로토콜을 따르는 모든 타입과 작업하도록 구현할 수 있다.
- 프로퍼티 래퍼의 목적은 비교작업을 하는 것이므로, Foundation프레임 워크에 포함된 Comparable프로토콜을 따르는 모든 데이터 타입을 지원하도록 수정해야 한다.
- Comparable 프로토콜을 따르는 타입은 값이 같은지, 더 큰지, 더 작은지를 비교하는 데 사용될 수 있다.
- String, Int, Date, DateInterval, 그리고 Character같은 다양한 값들의 타입이 이 프로토콜을 따른다.
요약
- 프로퍼티 래퍼는 코드의 중복 피하면서 앱 프로젝트의 코드를 통해 재사용되는 프로퍼티의 게터와 세터의 구현체를 사용할 수 있게 한다.
- 프로퍼티 래퍼는 지시자를 활용하여 구조체 + 클래스 형태로 선언된다.
- 강력한 스위프트 기능이다.