ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift - Property Wrapper Projecting Value
    Programming/Swift 2021. 11. 5. 10:43

     

     

    안녕하세요 BeePeach입니다 :)

    오늘은 지난 포스팅에 이어서 Property Wrapper에 대해서 공부해보도록 하겠습니다.

     

    바로 전 포스팅에서 Wrapper의 인스턴스에 접근하는 방법에 대해서 공부해보자고 했었죠??

    그럼 바로 시작하겠습니다!

     

     


    Wrapper의 인스턴스에 접근하기

     

    이전에 사용하던 예시와 다른 예시를 보겠습니다.

    이번에는 프로퍼티를 UserDefaults에 저장시키는 wrapper를 만들어보도록 하겠습니다.

     

     

    제네릭을 이용하여 확장성이 높은 코드로 만들었습니다.

    Value 타입을 UserDefaults에 저장하는 wrapper입니다.

    그럼 이 wrapper를 사용하여 구조체를 하나 만들어 보겠습니다.

     

    여기서 생성자에 UserDefaults에 추가하는 코드를 또 넣은 이유는 인스턴스를 만들면 처음에 UserDefaults에 아무것도 저장이 안돼서 넣어줬습니다.

    WWDC19에서 보면 이러한 코드가 없는것을 보면 playgound에서 발생하는 문제인거같습니다.

     

     

    기본적으로 volume을 60, stereo는 false로 초기화되도록 만들었습니다.

    그리고 바로 UserDefaults에 저장된것을 확인할 수 있습니다.

    값을 변경하면 변경된 값으로 UserDefaults에 새롭게 저장되는 것도 확인할 수 있습니다.

     

    만약 여기서 UserDefaults에서 삭제하는 기능도 추가를 하고 싶어질수도 있겠죠??

    그래서 UserDefaultsHelper에 UserDefaults에 저장된 값을 삭제하는 메서드를 추가해보겠습니다.

     

     

    remove 인스턴스 메서드를 추가시켰습니다.

    그럼 이 메서드를 SoundSetting 구조체에서 활용을 해보겠습니다.

     

     

    removeAll 메서드를 선언했으면 이제 이 안에서 wrapper에 인스턴스에 접근을 해서 remove 메서드를 호출해야 합니다.

    그런데 어떻게 wrapper의 인스턴스에 접근할까요...?

    Line 9와 같이 self.volume으로 접근하면 wrappedValue에 getter에서 리턴하는 값에 접근하게 됩니다. 

    wrapper의 인스턴스에 접근한 게 아닙니다.

     

    wrapper의 인스턴스에 접근하려면 wrapper를 추가한 프로퍼티 이름 앞에 _(underScore)를 붙여주면 됩니다.

    _volume으로 인스턴스 메서드인 remove를 호출할 수 있습니다.

     

    주의할 점은 이 기능은 private으로 설정되어있어서 외부에서 사용할 수 없습니다.

    그래서 외부에서 사용을 해보려고 하면 에러가 발생하는 것을 확인할 수 있습니다.

     

    그럼 만약 밖에서도 wrapper의 인스턴스에 접근하고 싶다면 어떻게 할까요????

     

     


    Projected Value

     

    이때 활용할 수 있는 게 projected value입니다.

    외부에서 wrapper의 인스턴스를 접근하고 싶을 때 사용한다고 했지만 원래의 용도는 훨씬 범용적입니다.

    Projected Value는 어떠한 값도 리턴할 수 있습니다.

    여러 가지 값 중에서 wrapper의 인스턴스를 리턴하도록 해서 사용하는 것일 뿐입니다.

     

    그럼 Projected Value를 이용해서 인스턴스를 반환할 수 있도록 하고 이를 통해서 외부에서도 wrapper의 인스턴스에 접근할 수 있도록 해보겠습니다.

     

     

    Line 6에 projectedValue라는 연산 프로퍼티를 선언했습니다.

    그리고 retuen self로 인스턴스를 리턴하도록 해주었습니다.

    (꼭 연산 프로퍼티일 필요가 없습니다. 저장 프로퍼티여도 됩니다. 그리고 꼭 self를 리턴하지 않아도 됩니다.)

     

    Wrapper를 사용하기 위해서 wrappedValue라는 프로퍼티를 철자가 틀리지 않게 선언하는 것처럼 projected value를 사용하고 싶다면 꼭 projectedValue 프로퍼티를 철자가 틀리지 않게 선언해야 합니다.

     

    그럼 이제 사용을 해볼까요??

     

     

    projectedValue를 선언했으면 $로 시작하는 프로퍼티를 사용할 수 있게 됩니다.

    이 프로퍼티를 이용하면  projectedValue의 return을 얻을 수 있고 우리는 return self로 wrapper의 인스턴스에 접근할 수 있도록 했습니다.

    wrapper의 인스턴스에 접근했으니 remove() 메서드를 사용할 수 있겠죠??

    그래서  UserDefaults에서 volume에 관련된 값만 remove를 한 것을 확인할 수 있습니다.

     

    이 예시만 보면 projectedValue의 활용성을 잘 모를 수 있으니 예전에 만들어본 HundredOrLess구조체로 다른 예시를 보도록 하겠습니다.

     

     


    다른 예시

     

    이전에 사용했었던 최댓값이 100이 넘지 않도록 하는 wrapper입니다.

    여기서 projectedValue는 이전과 다르게 저장 프로퍼티로 그리고 Bool 타입으로 지정했습니다.

    용도는 wrapper를 추가한 프로퍼티가 최댓값인 100을 넘는다면 projectedValue를 true 만들어서 최댓값이 넘는 값이 할당되려 했는지를 확인하는 용도입니다.

     

    아래에서 사용 예시를 보면 값이 100보다 작을 때 $value의 값은 false인 것을 확인할 수 있고 100이 넘는 값이 들어온다면 true를 리턴해주는 것을 확인할 수 있습니다.

     

    이런 식으로 활용 방법은 아주 무궁무진하므로 알아두신다면 조금 도움이 되겠죠??

     

     


     

    참고자료

     

    https://kxcoding.com

     

    여러분의 새로운 도전을 응원합니다 | KxCoding

    Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기

    kxcoding.com

     

     

    https://docs.swift.org/swift-book/LanguageGuide/Properties.html

     

    Properties — The Swift Programming Language (Swift 5.6)

    Properties Properties associate values with a particular class, structure, or enumeration. Stored properties store constant and variable values as part of an instance, whereas computed properties calculate (rather than store) a value. Computed properties a

    docs.swift.org

     

     

    728x90

    'Programming > Swift' 카테고리의 다른 글

    Swift - Subscript  (0) 2021.11.07
    Swift - Method  (0) 2021.11.06
    Swift - Property Wrapper  (0) 2021.10.28
    Swift - Type Property  (0) 2021.10.27
    Swift - Property Observer  (0) 2021.10.26
Designed by Tistory.