Property Wrapper
•
SwiftUI 에서 @ObservedObject, @State … 으로 만나게 되는..!
•
보일러플레이트 코드를 줄이기 위해 사용
Property Wrapper 사용 안했을 때 코드
struct House {
private var width = 0
var size: Int {
get { return width }
set { width = pow(newValue, 2) }
}
}
struct KoreaHouse {
private var _apartment = House()
private var _villa = House()
var apartmentSize: Int {
get { return _apartment.size }
set { _apartment.size = newValue }
}
var villaSize: Int {
get { return _villa.size }
set { _villa.size = newValue }
}
}
Swift
복사
⇒ KoreaHouse 구조체 내에서 각 프로퍼티에서 매번 동일한 보일러 플레이트 코드를 작성
Property Wrapper 사용
@propertyWrapper
struct House {
private var width = 0
var size: Int {
get { return width }
set { width = pow(newValue, 2) }
}
}
struct KoreaHouse {
@House var apartment: Int
@House var villa: Int
}
var koreaHouse = KoreaHouse()
koreaHouse.apartment = 20
koreaHouse.villa = 30
print(koreaHouse.apartment, koreaHouse.villa)
// 400, 900
Swift
복사
Property Wrapper 사용 + 생성자 버전
@propertyWrapper
struct House {
private var width = 0
var size: Int {
get { return width }
set { width = pow(newValue, 2) }
}
init(size: Int) {
widht = pow(newValue, 2)
}
}
struct KoreaHouse {
@House var apartment: Int = 20
@House var villa: Int = 30
}
var koreaHouse = KoreaHouse()
print(koreaHouse.apartment, koreaHouse.villa)
// 400, 900
Swift
복사
Projected Value
property wrapper가 저장하기 전에 값을 조정(adjust) 했는 지 알려줄 수 있음
@propertyWrapper
struct SmallNumber {
private var number: Int
private(set) var projectedValue: Bool
var wrappedValue: Int {
get { return number }
set {
if newValue > 12 {
number = 12
projectedValue = true
} else {
number = newValue
projectedValue = false
}
}
}
init() {
self.number = 0
self.projectedValue = false
}
}
Swift
복사
struct SomeStructure {
@SmallNumber var someNumber: Int
}
var someStructure = SomeStructure()
someStructure.someNumber = 4
print(someStructure.$someNumber)
// Prints "false"
someStructure.someNumber = 55
print(someStructure.$someNumber)
// Prints "true"
Swift
복사
UserDefault 에 적용
Ex)
@propertyWrapper
struct ImageString {
private var image: String = ""
private var fileExtension: String?
private let defaultExtension = ".png"
var wrappedValue: String {
get { self.image + (self.fileExtension ?? defaultExtension) }
set { self.image = newValue }
}
init(wrappedValue initialValue: String, fileExtension: String? = nil) {
self.image = initialValue
self.fileExtension = fileExtension ?? defaultExtension
}
}
struct UserProfile {
@ImageString var profileImage: String = ""
@ImageString(fileExtension: ".jpg") var IDImage: String = ""
}
let userProfile = UserProfile(profileImage: "phang", IDImage: "leechangjun")
print(userProfile.profileImage)
print(userProfile.IDImage)
Swift
복사