ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Property Wrapper
    Swift/SwiftUI 2023. 9. 28. 21:12

    SwiftUI에서 Property Wrappers는 특별한 기능을 갖는 속성을 정의하는 데 사용됩니다. Property Wrappers를 사용하면 코드를 간결하고 읽기 쉽게 만들 수 있습니다.

     

    • @State: 
    • SwiftUI 뷰의 상태를 저장하는 데 사용되며, 값을 변경할 때마다 뷰가 다시 렌더링됩니다. 보통 UI 컴포넌트의 상태를 저장하는 데 사용됩니다.

     

    • @Binding: 
    • 부모 뷰에서 자식 뷰로 값을 전달하고, 자식 뷰에서 부모 뷰로 값을 다시 전달하는 데 사용됩니다. 부모 뷰의 속성을 자식 뷰에서 변경하는 데 유용합니다.

     

    • @ObservedObject: 
    • 외부에서 제공되는 ObservableObject 프로토콜을 준수하는 객체의 상태를 저장하는 데 사용됩니다. 뷰에서 @ObservedObject 속성을 참조하면 해당 객체가 변경될 때마다 뷰가 다시 렌더링됩니다.

     

    • @EnvironmentObject: 
    • 앱의 전역 상태를 저장하는 데 사용됩니다. 앱의 다른 뷰에서도 동일한 객체에 접근하여 상태를 공유할 수 있습니다.

     

    • @FetchRequest: 
    • CoreData에서 데이터를 검색하는 데 사용됩니다. 뷰에서 CoreData의 적절한 엔터티와 조건을 설정하여 데이터를 가져올 수 있습니다.

     

     

    커스텀 프로퍼티 래퍼를 만드는 이유

    커스텀 프로퍼티 래퍼를 만드는 주된 이유는 프로젝트의 특정 요구사항에 맞춰 프로퍼티의 동작을 정확히 제어하고 싶을 때입니다. 

     

    예를 들어, 특정 값이 변경될 때마다 로그를 작성하거나, 프로퍼티의 값에 특정 변환을 적용하거나, 값의 유효성을 검사하는 등의 동작을 프로퍼티에 부여하고 싶을 때 커스텀 프로퍼티 래퍼를 사용할 수 있습니다.

     

     

    프로퍼티 래퍼에는 wrappedValue값이 있어야한다. 

    @propertyWrapper
    struct Uppercase {
        
        private var value: String = ""
        
        var wrappedValue: String {
            get { self.value }
            set { self.value = newValue.uppercased() }
        }
        
        init(wrappedValue initialValue: String) {
            self.wrappedValue = initialValue
        }
    }

    사용

    struct Address {
    
        @Uppercase var town: String
    }

     

    @propertyWrapper
    struct Uppercase {
            
        var wrappedValue: String {
            didSet {
                self.wrappedValue = wrappedValue.uppercased()
            }
        }
        
        init(wrappedValue initialValue: String) {
            self.wrappedValue = initialValue.uppercased()
        }
    }
    
    struct Address {
    
        @Uppercase var town: String
    }

     

     Swift 언어 자체에서 lazy 생성자를 언어 차원에서 제공해줍니다. 만약에 언어차원에서 지원하지 않고, 사용하고 싶은 경우, 다음과 같은 코드를 작성해줘야 합니다.

     

    지원 안해주면 구현해야할 코드

    struct Foo {
    	// lazy var foo = 1738
    	private var _foo: Int?
    	var foo: Int {
    		mutating get {
    			// 값이 있으면, 바로 리턴
    			if let value = self._foo { return value }
    			// 값이 없으면, 초기값을 리턴
    			let initialValue = 1738
    			self._foo = initialValue
    			return initialValue
    		} 
    		set {
    			self._foo = newValue
    		}
    	}
    }
    
    // 호출부
    var temp: Foo = Foo()
    print(temp.foo) // 초기값
    temp.foo = 123
    print(temp.foo) // 123''
Designed by Tistory.