Skip to content
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

Leaks related to UIViewControllerCoordinator #11

Open
trunghvbk opened this issue Aug 3, 2024 · 2 comments
Open

Leaks related to UIViewControllerCoordinator #11

trunghvbk opened this issue Aug 3, 2024 · 2 comments
Assignees

Comments

@trunghvbk
Copy link

trunghvbk commented Aug 3, 2024

Hi @vmanot,
In this sample code, I use UIViewControllerCoordinator to handle routing. I found that when I use it to assign .coordinator to the AView, AViewModel will never be released (The deinit func is never called).
It will not happen if I use AppKitOrUIKitWindowCoordinator. But in our legacy app, we use AppKitOrUIKitWindowCoordinator so it's hard to change.
Could you help to investigate the reason why it happens? I tried but have not yet found out.
Thank you!

import SwiftUI
import Coordinator

@main
struct CoordinatorTestApp: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
            }
        }
    }
}

enum ContentDestination {
    case aView
}

class ContentCoordinator: UIViewControllerCoordinator<ContentDestination> {
    override func transition(for route: ContentDestination) -> ViewTransition {
        switch route {
        case .aView:
            return .push(AView())
        }
    }
}

struct ContentView: View {
    @StateObject var coordinator = ContentCoordinator()
    var body: some View {
        VStack {
            Button {
                coordinator.trigger(.aView)
            } label: {
                Text("Go To AView")
            }
        }
        .padding()
        .coordinator(coordinator)
    }
}

struct AView: View {
    @StateObject var viewModel = AViewModel()
    @StateObject var coordinator = ACoordinator()

    var body: some View {
        VStack {
            Button {
                coordinator.trigger(.popBack)
            } label: {
                Text("Back")
            }
        }
        .coordinator(coordinator)
    }
}

class AViewModel: ObservableObject {
    deinit {
        // This will never run into
        debugPrint("AViewModel deinit")
    }
}

enum ADestination {
    case popBack
}

class ACoordinator: UIViewControllerCoordinator<ADestination> {
    override func transition(for route: ADestination) -> ViewTransition {
        switch route {
        case .popBack:
            return .pop
        }
    }
}

@vmanot vmanot self-assigned this Aug 3, 2024
@vmanot
Copy link
Member

vmanot commented Aug 3, 2024

@trunghvbk I'll investigate this, thanks!

If you're using Coordinator in your project, would you mind opening up a PR to contribute to documentation? I'm trying to encourage folks to contribute, it makes justifying and prioritizing this project a lot easier for me.

@trunghvbk
Copy link
Author

Hi @vmanot
What is the document that you mentioned? I see the How to Use is documented already.
Sorry I have not been good at documenting, but I will try to contribute to the source code with my ability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants