🖥️ Computer Science/👨🏻‍🎨 Design Pattern

[디자인패턴] 프로젝트에 Coordinator Pattern 적용 (3) - AppCoordinator 관리 & 순환참조 문제 해결

kyxxn 2024. 10. 16. 18:21

AppCoordinator가 사라져서 Main 화면 Issue List가 사라지는 문제 해결

기존 내 코드에는 다음과 같은 문제가 있었다.
다른 곳에서는 weak var coordinatorweak 키워드와 함께 관리가 되는데
하필 메인 화면인 IssueList에서만 weak를 사용하면 앱이 더이상 동작하지 않는다.

지난 번 팀원에게 내 SceneDelegate에서 AppCoordinator 관리가 잘못되었다고 짚어주셨다.

 

기존에 잘못된 내 코드

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    let navigationController = UINavigationController()

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        registerDependency()

        let issueListViewController = IssueListViewController()
        window?.rootViewController = UINavigationController(rootViewController: issueListViewController)
        let appCoordinator = AppCoordinator(navigationController: navigationController)
        appCoordinator.start()
        window?.rootViewController = navigationController
        window?.makeKeyAndVisible()
    }
}

메인 화면인 IssueList의 weak var coordinatorweak 설정을 하면
위와 같이 AppCoordinator도 사라지고, IssueListCoordinator도 사라지게 된다.

그래서 weak를 안 쓰고 사용하고 있었는데, 이건 잘못된 방법이라 판단

 

수정한 내 코드

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    let navigationController = UINavigationController()
    var appCoordinator: Coordinator?  // 여기서 프로퍼티로 갖고 있음 !!!

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        registerDependency()

        self.appCoordinator = AppCoordinator(navigationController: navigationController)
        appCoordinator?.start()
        window?.rootViewController = navigationController
        window?.makeKeyAndVisible()
    }
}

  • 기존의 코드는 SceneDelegate에서 AppCoordinator를 메소드 내의 지역 객체로 만든 경우이다.
    • 이때 AppCoordinator.start()를 해서 생성된 IssueListCoordinator를 AppCoordinator로 지정하는데, SceneDelegate 메소드가 끝나면 더이상 IssueListCoordinator를 접근할 수 있는게 없다..? 라고 이해했다 (순환참조 문제 이렇게 이해하는게 맞는지 모르겠다)
    • ARC에 대해 다시 공부해야할 필요성을 느꼈다.
  • 수정한 코드는은 SceneDelegate에서 프로퍼티로 AppCoordinator를 계속 들고 있어서 유지할 수 있게 하여 다음과 같이 해결했다.

 

Coordinator끼리 순환참조 문제 해결

  • 코디네이터 내부에 finishDelegate가 있는데 그걸 weak var가 아닌 그대로 선언해버려서 서로 묶여버리는 순환참조가 발생했다.
  • weak 키워드를 붙임으로써 해결할 수 있었다.