-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
프로젝트 매니저 [STEP 2-1] BMO #311
base: ic_9_bmo94
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
뷰를 어떻게 그리느냐 보다는
뷰모델과 뷰를 어떻게 바인딩 하고
스트림이나, 이벤트, 상태 관리를 어떻게 할지를 조금 더 중점적으로
고민해보시면 좋을 듯 싶습니다
|
||
import Foundation | ||
|
||
struct Work { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
모델들은 앵간하면 equatable, identifiable, sendable하면 좋아요
설계할 때 고려해주세요
import UIKit | ||
|
||
final class WorkCell: UITableViewCell { | ||
static let identifier: String = "WorkCell" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요런건 항상 프로토콜을 사용하는 습관이 좋을 듯 합니당
|
||
private let titleLabel: UILabel = { | ||
let label = UILabel() | ||
label.numberOfLines = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1은 굳이 안해줘도 될 걸요?
super.init(style: style, reuseIdentifier: reuseIdentifier) | ||
setUI() | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prepare for reuse를 처리하는 부분이 없네요
enum WorkType: String { | ||
case todo = "TODO" | ||
case doing = "DOING" | ||
case done = "DONE" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
work에 nested로 있어도 괜찮을거 같다는 생각이 드네요
|
||
import Foundation | ||
|
||
final class WorkViewModel { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
보통 뷰 모델을 정의할 때에는
뷰에서 받을 입력값
뷰의 상태를 업데이트 해줄 수 있는 방법(함수를 실행, observable을 구독, 상태 값을 구독) 등이 필요할거 같고,
해당 방법 들에 대해서는 조금 더 고민해보시면 좋을 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여러개의 ViewModel
일반적으로는 뷰 하나에 뷰모델 하나를 매핑해서 사용하는게 좋을 것 같아요
다만 뷰컨 즉 화면 하나랑은 다른 얘기인데
뷰를 쪼개서 해당 뷰의 기능만 하는 뷰모델을 두고
여러개의 뷰로 화면을 구현해야해요
또한 @published를 쓸 경우 observable은 의미가 없어질거고,
ios17부터는 @observable이라는 매크로가 나와서
요걸 활용하면 좋을 것 같아요
@havilog
안녕하세요 하비!
연휴는 잘 보내셨나요? 😄
프로젝트 매니저 STEP 2-1 PR 전송드립니다.
이번 스텝에서는 뷰(완전하지 않은 상태) + MVVM 적용까지 진행했습니다.
고민했던 점
MVVM 구현
Closure를 이용하는 방법
Observable을 이용하는 방법
didChangeWorks
에,Observable
을 이용하는 경우listener
에 바인드 할 작업을 지정합니다.work
가 변동될 때,Observable
을 이용하는 경우value
가 변동될 때didSet
에서 바인딩 된 작업을 호출합니다.저는 두 방식이 거의 유사하다고 생각하여 처음에는 코드 량이 좀 더 적은 클로저를 이용하는 방식으로 코드를 작성했습니다. 하지만 도중에
Observable
을 사용하는 방법으로 코드를 변경하게 되었습니다.사유는 초기화 시점에 있었습니다.
클로저 방식은 초기화시
works
에 값이 대입된다 하더라도, 바인딩 되는 시점에ViewModel
에서works
값을 직접 조회하지 않는 이상 해당ViewModel
을 가지고 있는 곳에서works
와 바인딩 되어있는 값에 영향을 줄 수 없는 상태입니다.그래서 직접
ViewModel
로부터 값을 조회하거나,ViewModel
에게 초기화가 끝났다는 노티를 전송해야 합니다.Observable
을 사용하는 경우 모든 과정이 클로저의 경우와 같으나bind
에 있는listener(value)
로 인해 별도 조회나 노티 전송 없이 현재 값이 바로 바인딩 된 상태가 됩니다.별도로 바인드 후 값을 대입하는 과정이나, 노티를 전송하는 작업 없이 해당 코드만으로 데이터 바인딩 되는 것이 깔끔하다고 생각해
Observable
을 활용하는 방식을 택했습니다.조언을 구하는 점
여러개의 ViewModel
처음에는 하나의
ViewModel
이 여러개의Model
을 가진 상태로 해당ViewModel
을View
의 의존성으로 전달하는 방식을 생각했습니다. 하지만 이 경우View
가 추가되거나 제거될 때 해당ViewModel
내의 코드를 변경시켜야 된다고 생각해 각각의 뷰가 각각의ViewModel
을 가지고 있는 형태로 변경했습니다.처음에 시도한 방식과, 수정 한 방식 중 어떤 식으로 사용하는 것이 좀 더 보편적인(?) 방식인지 궁금합니다.