You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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)
}

}

我尝试过的临时解决方法

我发现如果把inviteRegistrationButtonaddTarget参数里的LoginController.self换成self,App就能正常跳转了,但Xcode会弹出一个警告。我不太理解为什么原来的写法会触发崩溃,也想知道怎么才能正确处理这个问题,既解决崩溃又消除警告。

(登录界面截图:[登录界面])

备注:内容来源于stack exchange,提问作者IsaacNewtonGravity

火山引擎 最新活动