문제 상황
- View를 채택하는 VC에 bind(reactor:) 메서드가 실행되지 않음
원인 분석
- Coordinator에서 push메서드에 reactor를 생성자에 주입하니 메서드가 실행되지 않았음
/// 운동 편집 화면 전체 화면으로 push
func pushEditExcerciseView(routineName: String) {
let reactor = EditExcerciseViewReactor(routineName: routineName)
let editExcerciseVC = EditExcerciseViewController(reactor: reactor)
navigationController.pushViewController(editExcerciseVC, animated: true)
}
해결 방안
- VC의 reactor 프로퍼티에 직접 할당하는 코드를 추가
/// 운동 편집 화면 전체 화면으로 push
func pushEditExcerciseView(routineName: String) {
let reactor = EditExcerciseViewReactor(routineName: routineName)
let editExcerciseVC = EditExcerciseViewController(reactor: reactor)
editExcerciseVC.reactor = reactor
navigationController.pushViewController(editExcerciseVC, animated: true)
}
왜 이방법으로 실행이 됬는가?
- VC내부에 reactor 프로퍼티가 존재
- View 프로토콜을 까보면 bind(reator:) 메서드는 reactor가 할당되면 실행되도록 구현되어 있음 (아래 코드블럭 🔥 이모지 확인)
public protocol View: AnyObject {
associatedtype Reactor: ReactorKit.Reactor
/// A dispose bag. It is disposed each time the `reactor` is assigned.
var disposeBag: DisposeBag { get set }
/// A view's reactor. `bind(reactor:)` gets called when the new value is assigned to this property.
var reactor: Reactor? { get set }
/// Creates RxSwift bindings. 🔥 This method is called each time the `reactor` is assigned 🔥
///
/// Here is a typical implementation example:
///
/// ```
/// func bind(reactor: MyReactor) {
/// // Action
/// increaseButton.rx.tap
/// .bind(to: Reactor.Action.increase)
/// .disposed(by: disposeBag)
///
/// // State
/// reactor.state.map { $0.count }
/// .bind(to: countLabel.rx.text)
/// .disposed(by: disposeBag)
/// }
/// ```
///
/// - warning: It's not recommended to call this method directly.
func bind(reactor: Reactor)
결론
- VC내부에 선언된 reactor 프로퍼티에 할당해줘야 정상적으로 실행되는 것
- reactor 프로퍼티를 선언하지 않고, 생성자를 통해 reactor을 할당해줘도 bind가 실행됨 (아래코드 예시)
이전코드
final class EditExcerciseViewController: UIViewController, View {
typealias Reactor = EditExcerciseViewReactor
/// 메모리 해제를 위한 DisposeBag (RxSwift)
var disposeBag = DisposeBag()
/// ReactorKit 또는 MVVM 패턴을 위한 리액터 객체입니다.
private let reactor: EditExcerciseViewReactor
/// 외부에서 리액터를 주입받아 초기화합니다.
init(reactor: EditExcerciseViewReactor) {
super.init(nibName: nil, bundle: nil)
self.reactor = reactor
}
수정코드
final class EditExcerciseViewController: UIViewController, View {
typealias Reactor = EditExcerciseViewReactor
/// 메모리 해제를 위한 DisposeBag (RxSwift)
var disposeBag = DisposeBag()
/// 외부에서 리액터를 주입받아 초기화합니다.
init(reactor: EditExcerciseViewReactor) {
super.init(nibName: nil, bundle: nil)
self.reactor = reactor
}
'iOS' 카테고리의 다른 글
Github Action으로 CI 구성하기 (1) | 2025.06.04 |
---|---|
왜 POP? (WWDC15) (0) | 2025.06.02 |
[트러블 슈팅] DiffableDataSource 컬렉션 뷰에 다양한 데이터모델을 사용하기 (0) | 2025.05.02 |
[트러블 슈팅] CoreData의 Entity Attribute의 타입을 변경한 경우 (0) | 2025.04.23 |
메모리 사용량 확인을 위한 vmmap (1) | 2025.03.18 |