gpt4 book ai didi

swift - UIViewController 不取消初始化(mvvm + 协调器)

转载 作者:行者123 更新时间:2023-11-28 06:00:03 27 4
gpt4 key购买 nike

因为这个问题,我很头疼。为什么我的 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)
}
}

还有一些来自 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)
})
}
...

预先感谢您的回答!

最佳答案

我可以看到如何阻止 SplashscreenViewController 释放的两种方法如下:

  1. 如果它是 rootViewControllerwindow 没有被释放。请记住,应用程序会保留关键窗口。
  2. 在您的start() 函数中,Observable 闭包保留了vc 变量。此 Observable 可能会保留在别处,无论是显式保留还是在 DisposeBag 中。

关于swift - UIViewController 不取消初始化(mvvm + 协调器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50097291/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com