我有一個 LoginCoordinator 類,它的 start() 方法實體化了 LoginViewController。但即使在從 LoginCoordinator 分配 LoginViewController 中的 coordinator 變數之后,“有時”視圖控制器中的 coordinator 變數也為零。
“有時”我的意思是,當我除錯并在 start() 方法中保留斷點時,會分配該值。
這是我的登錄協調器
class LoginCoordinator: Coordinator {
var navigationController: UINavigationController
weak var parent: MainCoordinator?
var childCoordinators: [Coordinator]?
init(navController: UINavigationController) {
self.navigationController = navController
}
func start() {
let vc: LoginViewController = UIStoryboard.main.instantiateViewController()
vc.coordinator = self
navigationController.pushViewController(vc,animated: true)
}
func goToSignUp() {
let signUpCoordinator = SignUpCoordinator(navController: navigationController)
childCoordinators?.append(signUpCoordinator)
signUpCoordinator.start()
}
func goToHomeVC() {
let homeCoordinator = HomeCoordinator(navControl: navigationController)
childCoordinators?.append(homeCoordinator)
homeCoordinator.start()
}
}
這是我的 LoginViewController
class LoginViewController: UIViewController {
@IBOutlet weak private var userName: HubTextField!
@IBOutlet weak private var password: HubTextField!
@IBOutlet weak private var forgotPassword: UILabel!
@IBOutlet weak var loginButton: HubButton!
var viewModel: LoginSignupVM = .init(totalItem: 2)
weak var coordinator: LoginCoordinator?
fileprivate func setupForgotPassword() {
forgotPassword.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(forgotTapped))
forgotPassword.addGestureRecognizer(tapGesture)
}
override func viewDidLoad() {
super.viewDidLoad()
loginButton.appearance = Appearance(cornerRadius: loginButton.frame.height/2)
loginButton.setTitle(TitleText.loginText, for: .normal)
loginButton.isEnabled = false
setupTextField()
hideKeyboardWhenTappedAround()
setupForgotPassword()
setupNavigationBar()
// MARK: remove this later
userName.text = "[email protected]"
password.text = "asdfg123"
}
private func setupNavigationBar() {
let titleView = UILabel(frame: .zero)
titleView.text = "Login Up"
titleView.font = UIFont.systemFont(ofSize: 20)
navigationItem.titleView = titleView
rightButton()
}
fileprivate func rightButton() {
let rightButton = UIBarButtonItem(title: "signUp", style: .plain, target: self, action: #selector(goToSignUPScreen))
rightButton.title = "sign Up"
navigationItem.rightBarButtonItem = rightButton
}
@objc private func goToSignUPScreen() {
coordinator?.goToSignUp()
}
@objc private func backButtonClicked() {
navigationController?.popViewController(animated: true)
}
@objc private func forgotTapped() {
//MARK: todo forgot password
}
private func assignTags() {
userName.tag = 0
password.tag = 1
}
private func setupTextField() {
userName.placeHolder = TitleText.email
userName.textFieldType = .email
userName.delegate = self
password.placeHolder = TitleText.password
password.textFieldType = .password
password.delegate = self
assignTags()
}
private func goToHomeViewController() {
coordinator?.goToHomeVC()
}
@IBAction func onLoginClick(_ sender: Any) {
//MARK: todo login click change hardcoded verification
if let email = userName.text, let password = password.text {
if email == "[email protected]" && password == "asdfg123" {
goToHomeViewController()
}
}
}
}
extension LoginViewController: ValidatorButton {
func addNewValidated(tag: Int, result: ValidationResult) {
viewModel.validationList[tag] = result
loginButton.isEnabled = viewModel.loginButtonEnabled()
}
}
從 MainCoordinator 呼叫 LoginCoordinator 為:
class MainCoordinator: Coordinator {
var isLogin: Bool = false
var navigationController: UINavigationController
var childCoordinators: [Coordinator]? = []
let window: UIWindow?
init(navController: UINavigationController, window: UIWindow) {
self.navigationController = navController
self.window = window
}
func start() {
if isLogin {
let child = HomeCoordinator(navControl: navigationController)
childCoordinators?.append(child)
child.start()
} else {
let child = LoginCoordinator(navController:
navigationController)
childCoordinators?.append(child)
child.start()
}
}
}
并且 MainCoordinator 是從 sceneDelegate 呼叫的,如下所示:
func scene(_ scene: UIScene, willConnectTo session:
UISceneSession, options connectionOptions:
UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: scene)
self.window = window
let navigationController = UINavigationController()
let mainCoordinator = MainCoordinator(navController:
navigationController,window: window)
mainCoordinator.start()
window.rootViewController = navigationController
window.makeKeyAndVisible()
}
uj5u.com熱心網友回復:
mainCoordinator在willConnectTo委托方法中被宣告為區域變數:
let mainCoordinator = MainCoordinator(navController:
navigationController,window: window)
這意味著它可以在willConnectTo.
由于mainCoordinator持有對 的唯一強參考LoginCoordinator,它也將被釋放。這就是為什么您nil在視圖控制器中看到的原因- 那時,mainCoordinator已被釋放。
你仍然會在 中看到一個非 nil 值LoginCoordinator.start,因為那時mainCoordinator.start還沒有完成,所以mainCoordinator還沒有被釋放。
為了解決這個問題,您可以通過宣告一個名為 的屬性,使場景委托持有對主協調器的強參考mainCoordinator:
var mainCoordinator: MainCoordinator!
// in willConnectTo:
mainCoordinator = MainCoordinator(navController:
navigationController,window: window)
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/396900.html
