4INCENSE / geha-sajang-iOS

1 stars 0 forks source link

View 클래스 리팩토링 #17

Closed dev-Lena closed 3 years ago

dev-Lena commented 3 years ago

11 에서

Notification를 보내는 클래스와 Notification을 받고 뷰를 업데이트하는 뷰 클래스의 프로퍼티와 메소드가 똑같아 중복된 코드를 매번 쓰기 보다 Protocol과 Extension을 사용하여 구현하는 방법으로 리팩토링하기로 했습니다.

Notification을 보내는 객체

Notification을 받고 View를 업데이트하는 객체



Label 클래스와 TextField 클래스 공통 부분

properties

Methods

TextField 클래스에 더 있는 부분

properties

Methods

Extension 구현

properties

dev-Lena commented 3 years ago

Protocol + Extension 으로 중복되는 코드를 구현하려고 하였으나 몇 가지 제약이 있어서 상속으로 구현

만난 제약

  1. Protocol로 선언하려는 메소드 중 Notification의 Selector로 불리는 @objc 메소드 존재:

    • objc 메소드는 objc 프로토콜에서만 구현 가능

      @objc can only be used with members of classes, @objc protocols, and concrete extensions of classes

    • 이곳에서 필요한 objc 메소드는 Notification의 selector 메소드로 Notification의 userInfo에서 state를 꺼내 viewState(저장 프로퍼티)를 업데이트 해줌. 하지만 프로토콜의 extension에서는 저장 프로퍼티

    • 그럼 objc 프로토콜에서 업데이트할 저장 프로퍼티를 지정해주면 되지 않을까? 라고 생각했지만 objc 프로토콜에 저장 프로퍼티를 만들면

      Property cannot be a member of an @objc protocol because its type cannot be represented in Objective-C

    • 이런 메세지가 뜨고 프로퍼티 앞에 objc를 붙이면

      Property cannot be marked @objc because its type cannot be represented in Objective-C
      이런 메시지가 뜸.

    • 그리고 이 objc 프로토콜을 상속한 곳에서 저장 프로퍼티를 선언하면 이런 메시지가 뜸

      Property cannot be an implementation of an @objc requirement because its type cannot be represented in Objective-C

    • UpdateState 메소드를 objc 프로토콜(UpdateState프로토콜)을 extension해서 구현하려고 했을 때 func 앞에 objc를 붙이면 이런 메세지가 뜸

      @objc can only be used with members of classes, @objc protocols, and concrete extensions of classes

    • 붙이지 않고 UpdateState프로토콜을 채택해서 구현하려고 하면

      Non-'@objc' method 'updateState' does not satisfy requirement of '@objc' protocol 'UpdateState'
      라고 나옴.

즉,

공통적인 부분은 프로토콜로 명시를 해주고 extension으로 구현하려고 했지만 메소드 중 저장 프로퍼티의 값을 바꾸고, 그 값이 바뀌면 다른 메소드를 불리는 흐름을 갖고있는 조합이었기 때문에 적합하지 않았음. + 공통 프로퍼티와 메소드를 프로토콜로, Notification의 Selector 메소드를 objc 프로토콜로 명시한 후 extension으로 구현하는 것은 적절하지 않은 케이스라고 판단함.

그래서 공통된 부분만 ViewUpdating 프로토콜로 생성 후 UITextField을 상속하고 ViewUpadating을 채택한 TextFieldObserver와 UILabel을 상속하고 ViewUpadating을 채택한 LabelObserver 클래스 생성

상위 클래스 상속 후 각 뷰 클래스 에서는

  1. 각 뷰 클래스마다 observer로 등록/ 등록해지하는 Notification 등록/ 등록 해제
  2. 특히 TextField는 Placeholder에 들어가는 각기 다른 메세지 설정
dev-Lena commented 3 years ago

구현 완료로 이슈 클로즈 하겠습니다.

dev-Lena commented 3 years ago

image