Swift UIViewController未取消初始化(mvvm和协调器)

Swift UIViewController未取消初始化(mvvm和协调器),swift,mvvm,rx-swift,swinject,coordinator-pattern,Swift,Mvvm,Rx Swift,Swinject,Coordinator Pattern,因为这个问题,我头疼。为什么我的SplashscreenViewController没有取消初始化?你们在下面的代码中看到了任何潜在的保留周期吗? 我试图检查Malloc堆栈,但找不到任何有用的信息 final class SplashscreenViewController: UIViewController { var viewModel: SplashscreenViewModelType! private let animationStartScale: CGFloat

因为这个问题,我头疼。为什么我的SplashscreenViewController没有取消初始化?你们在下面的代码中看到了任何潜在的保留周期吗? 我试图检查Malloc堆栈,但找不到任何有用的信息

final class SplashscreenViewController: UIViewController {
    var viewModel: SplashscreenViewModelType!

    private let animationStartScale: CGFloat = 0.75
    private let animationEndScale: CGFloat = 1.0
    private let animationDuration: TimeInterval = 0.4

    private let splashscreenDuration: TimeInterval = 1.5

    @IBOutlet private weak var logoImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        animateLogo(scale: animationStartScale)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        DispatchQueue.main.asyncAfter(deadline: .now() + splashscreenDuration, execute: { [weak self] in
            self?.viewModel.onFinish.onNext(())
        })
    }

    private func animateLogo(scale: CGFloat) {
        UIView.animate(withDuration: animationDuration, animations: {
            self.transformImage(scale: scale)
        }, completion: { _ in
            if scale == self.animationStartScale {
                self.animateLogo(scale: self.animationEndScale)
            } else {
                self.animateLogo(scale: self.animationStartScale)
            }
        })
    }

    private func transformImage(scale: CGFloat) {
         logoImageView.transform = CGAffineTransform(scaleX: scale, y: scale)
    }
}
保存SplaschreenViewController实例的类是它的协调器。代码如下:

final class SplashscreenCoordinator: BaseCoordinator {
    private let window: UIWindow

    init(window: UIWindow) {
        self.window = window
    }

    override func start() -> Observable<Void> {
        let vc: SplashscreenViewController = SwinjectStoryboard.instantiateInitialViewController()
        window.rootViewController = vc
        window.makeKeyAndVisible()

        let onFinish = vc.viewModel.onFinish
            .asObservable()
            .flatMap { [unowned self] _ -> Observable<Void> in
                guard self.window.rootViewController == vc else {
                    return Observable<Void>.empty()
                }
                if UserPreferencesManager.isLoggedIn() {
                    return self.startAppForLoggedInUser()
                } else {
                    return self.startAppForAnonymousUser()
                }
            }

        return onFinish
    }

    private func startAppForLoggedInUser() -> Observable<Void> {
        let tabBar = TabBarCoordinator(window: window)
        return coordinate(to: tabBar)
    }

    private func startAppForAnonymousUser() -> Observable<Void> {
        let startCoordinator = StartCoordinator(window: window)
        return coordinate(to: startCoordinator)
    }
}
final类协调员:BaseCoordinator{
私人出租窗口:UIWindow
初始化(窗口:UIWindow){
self.window=window
}
覆盖func start()->可观察{
让vc:SplashscreenViewController=SwinjectStoryboard.InstanceInitialViewController()
window.rootViewController=vc
window.makeKeyAndVisible()的
设onfish=vc.viewModel.onfish
.asObservable()
.flatMap{[unowned self]\在中可观察到
guard self.window.rootViewController==vc else{
返回可观察的.empty()
}
if UserPreferencesManager.isLoggedIn(){
返回self.startAppForLoggedInUser()
}否则{
return self.startappforanymousser()
}
}
返回完成
}
private func startAppForLoggedInUser()->可观察{
让tabBar=tabBar协调器(窗口:窗口)
返回坐标(到:选项卡栏)
}
private func startappforanymousser()->可观察{
让startCoordinator=startCoordinator(窗口:窗口)
返回坐标(到:startCoordinator)
}
}
还有来自BaseCoordinator的一些代码:

...
private func store(coordinator: BaseCoordinator) {
    childCoordinators[coordinator.identifier] = coordinator
}

private func free(coordinator: BaseCoordinator) {
    childCoordinators[coordinator.identifier] = nil
}

func coordinate(to coordinator: BaseCoordinator) -> Observable<Void> {
    store(coordinator: coordinator)
    return coordinator.start()
        .do(onNext: { [weak self] _ in
            self?.free(coordinator: coordinator)
        })
}
...
。。。
专用func商店(协调人:BaseCoordinator){
childCoordinators[coordinator.identifier]=协调员
}
private func free(协调器:BaseCoordinator){
childCoordinators[coordinator.identifier]=nil
}
func坐标(到协调器:BaseCoordinator)->可观察{
门店(协调员:协调员)
返回协调器.start()
.do(onNext:{[弱自我]uuIn
自我?.free(协调员:协调员)
})
}
...

提前感谢您的回答

我可以通过以下两种方式了解如何阻止
SplashscreenViewController
解除分配:

  • 如果它是
    rootViewController
    窗口
    未解除分配。请记住,应用程序保留“关键点”窗口
  • start()
    函数中,
    Observable
    闭包保留了
    vc
    变量。这个
    可观察的
    可能会被明确地或在
    DisposeBag
    中保留在其他地方