[Swift] 프로퍼티 래퍼

Jade·2023년 7월 24일
0

TIL

목록 보기
7/10

프로퍼티 래퍼에 대해서 Araboza


  • 프로퍼티 래퍼는 클래스(class)와 구조체(struct)의 구현부에 getter, setter, 연산 프로퍼티 코드의 중복을 줄이는 방법을 제공한다. (Swift 5.1부터 생김)

  • 여러 클래스나 구조체에 생성한 연산 프로퍼티들이 유사한 패턴을 갖는 경우가 발생해서 불편할 때가 있다.
    - 이 때, 프로퍼티 래퍼를 사용하면 연산 프로퍼티 기능을 개별 클래스, 구조체와 분리할 수 있고, 앱 코드에서 재사용할 수 있다.

예제

  • 다음과 같이 도시 이름을 저장하는 String 프로퍼티를 가진 구조체가 있다고 하자.
struct Address {
	private var cityName: String

	var city: String {
		get { cityName }
		set { cityName = newValue.uppercased()}
	}
}
  • 사용자가 도시 이름을 어떻게 입력했는지와는 상관 없이 대문자로 저장되어야 한다면 다음과 같이 연산 프로퍼티를 구조체에 추가할 수 있다.

  • 도시 이름 프로퍼티에 할당되면 연산 프로퍼티의 setterprivate cityName 변수에 값을 저장하기 전에 대문자로 변환하게 된다.

var address = Address()
address.city = "Seoul"
print(address.city) // LONDON
  • 연산 프로퍼티를 사용하는 대신에 이 로직을 프로퍼티 래퍼로 구현할 수 있다.
@propertyWrapper // 이 지시자를 이용하여 선언
struct FixCase {
	private(set) var value: String = ""

	var wrappedValue: String {
		get { value }
		set { value = newValue.uppercased() }
	}
	init(wrappedValue initialValue: String) {
		self.wrappedValue = initialValue
	}
}
  • 모든 프로퍼티 래퍼는 값을 변경하거나 유효성을 검사하는 getter, setter 코드가 포함된 wrappedValue 프로퍼티를 가져야 한다.

    • 초깃값이 전달되는 초기화 메서는 선택 사항으로 포함될 수도 있다.
    • 위 코드의 초깃값(init) 에서는 문자열을 대문자로 변환하고 private 변수에 저장하는 프로퍼티에 할당한다.

  • 이제 래퍼에 대한 정의가 끝났으니 이와 동일한 동작이 필요한 다른 프로퍼티 변수에 적용하여 재사용할 수 있다.
struct Contact {
	@FixCase var name: String // FixCase동작이 필요한 프로퍼티 앞에 @FixCase를 붙인다.
	@FixCase var city: String
	@FixCase var country: String
}

var contact = Contact(name: "GilDong", city: "Seoul", country: "Korea")

print("\(contact.name), \(contact.city), \(contact.country)")
// GILDONG, SEOUL, KOREA
  • 이처럼 미리 정의된 프로퍼티 래퍼는 나중에 설명할 SwiftUI 작업을 할 때 광범위하게 사용된다.
profile
응애 iOS 개발자

0개의 댓글