Swift iOS项目在Xcode中触发“unrecognized selector sent to class”错误的问题求助
Swift iOS项目在Xcode中触发“unrecognized selector sent to class”错误的问题求助
我正在跟着Udemy的课程做一个简易Instagram克隆项目,现在遇到了一个运行时崩溃问题,希望能得到大家的帮助。
环境信息
- Xcode版本:14.2
- macOS版本:Monterey 12.6.5
- iOS模拟器版本:16.2
错误详情
当我点击登录界面底部的**"Don't have an account? Sign Up"**按钮时,App直接崩溃,控制台抛出以下错误:
Thread 1: "+[InstagramFirestoreTutorial.LoginController presentRegistrationController]: unrecognized selector sent to class 0x10b086788"
错误指向LoginController里尝试跳转注册页面的方法,代码位置在第118行:
@objc func presentRegistrationController() { let registrationController = RegistrationController() navigationController?.pushViewController(registrationController, animated: true) }
相关代码
LoginController.swift
// // LoginController.swift // InstagramFirestoreTutorial // // Created by *** on 27/02/2023. // import UIKit class LoginController: UIViewController { // MARK: - Class Properties private let iconImageView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "Instagram_logo_white")!) imageView.contentMode = .scaleAspectFill imageView.translatesAutoresizingMaskIntoConstraints = false return imageView }() private let emailTextField: CustomTextField = { let textField = CustomTextField(placeholder: "Email") textField.keyboardType = .emailAddress return textField }() private let passwordTextField: CustomTextField = { let textField = CustomTextField(placeholder: "Password") textField.isSecureTextEntry = true return textField }() private lazy var stackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [emailTextField, passwordTextField, logInButton, passwordRetrievalButton]) stackView.axis = .vertical stackView.spacing = 20 stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() private let logInButton: UIButton = { let button = UIButton(type: .system) button.setTitle("Log In", for: .normal) button.setTitleColor(.white, for: .normal) button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20.0) button.backgroundColor = UIColor(named: "logInButton") button.layer.cornerRadius = 5.0 button.setHeight(50.0) button.translatesAutoresizingMaskIntoConstraints = false return button }() private let inviteRegistrationButton: UIButton = { let button = UIButton(type: .system) button.setAttributedTitle(withQuestion: "Don't have an account?", andAction: "Sign Up") button.addTarget(LoginController.self, action: #selector(presentRegistrationController), for: .touchUpInside) return button }() private let passwordRetrievalButton: UIButton = { let button = UIButton(type: .system) button.setAttributedTitle(withQuestion: "Forgotten your password?", andAction: "Get help logging in") return button }() // MARK: - Class Lifecycle Methods override func viewDidLoad() { super.viewDidLoad() configureUI() } // MARK: - Class Supplementary Methods private func configureUI() { view.backgroundColor = .white navigationController?.navigationBar.isHidden = true navigationController?.navigationBar.barStyle = .black configureGradientLayer() configureSubviews() } private func configureSubviews() { view.addSubview(iconImageView) NSLayoutConstraint.activate([ iconImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor), iconImageView.heightAnchor.constraint(equalToConstant: 80.0), iconImageView.widthAnchor.constraint(equalToConstant: 120.0), iconImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 32.0) ]) view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.topAnchor.constraint(equalTo: iconImageView.bottomAnchor, constant: 32.0), stackView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 32.0), stackView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -32.0) ]) view.addSubview(inviteRegistrationButton) NSLayoutConstraint.activate([ inviteRegistrationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), inviteRegistrationButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) } // MARK: - Button Action Selector Functions @objc func presentRegistrationController() { let registrationController = RegistrationController() navigationController?.pushViewController(registrationController, animated: true) } }
RegistrationController.swift
// // RegistrationController.swift // InstagramFirestoreTutorial // // Created by **** on 27/02/2023. // import UIKit class RegistrationController: UIViewController { // MARK: - Class Properties private let profilePhotoButton: UIButton = { let button = UIButton(type: .system) button.setImage(UIImage(named: "plus_photo"), for: .normal) button.tintColor = .white button.translatesAutoresizingMaskIntoConstraints = false return button }() private let emailTextField: CustomTextField = { let textField = CustomTextField(placeholder: "Email") textField.keyboardType = .emailAddress return textField }() private let passwordTextField: CustomTextField = { let textField = CustomTextField(placeholder: "Password") textField.isSecureTextEntry = true return textField }() private let fullnameTextField = CustomTextField(placeholder: "Fullname") private let usernameTextField = CustomTextField(placeholder: "Username") private let signUpButton: UIButton = { let button = UIButton(type: .system) button.setTitle("Sign Up", for: .normal) button.setTitleColor(.white, for: .normal) button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20.0) button.backgroundColor = UIColor(named: "signUpButton") button.layer.cornerRadius = 5.0 button.setHeight(50.0) button.translatesAutoresizingMaskIntoConstraints = false return button }() private lazy var stackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [emailTextField, passwordTextField, fullnameTextField, usernameTextField, signUpButton]) stackView.axis = .vertical stackView.spacing = 20 stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() private let inviteToLogInButton: UIButton = { let button = UIButton(type: .system) button.setAttributedTitle(withQuestion: "Already have an account?", andAction: "Log In") button.addTarget(RegistrationController.self, action: #selector(presentLogInController), for: .touchUpInside) return button }() // MARK: - Class Lifecycle Methods override func viewDidLoad() { super.viewDidLoad() configureUI() } // MARK: - Class Supplementary Methods private func configureUI() { configureGradientLayer() addUISubviews() navigationController?.navigationBar.isHidden = true } private func addUISubviews() { view.addSubview(profilePhotoButton) NSLayoutConstraint.activate([ profilePhotoButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), profilePhotoButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 32.0), profilePhotoButton.widthAnchor.constraint(equalToConstant: 140.0), profilePhotoButton.heightAnchor.constraint(equalToConstant: 140.0) ]) view.addSubview(stackView) NSLayoutConstraint.activate([ stackView.topAnchor.constraint(equalTo: profilePhotoButton.bottomAnchor, constant: 32.0), stackView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 32.0), stackView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -32.0) ]) view.addSubview(inviteToLogInButton) NSLayoutConstraint.activate([ inviteToLogInButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), inviteToLogInButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) } @objc func presentLogInController() { navigationController?.popViewController(animated: true) } }
我尝试过的临时解决方法
我发现如果把inviteRegistrationButton的addTarget参数里的LoginController.self换成self,App就能正常跳转了,但Xcode会弹出一个警告。我不太理解为什么原来的写法会触发崩溃,也想知道怎么才能正确处理这个问题,既解决崩溃又消除警告。
(登录界面截图:[登录界面])
备注:内容来源于stack exchange,提问作者IsaacNewtonGravity




