KAinone
@KAinone

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

エラー EXC_BAD_ACCESS

解決したいこと

コードのみでUIを生成しています。
シミュレーターを起動したところすぐに落ちてしまい、該当コード内の UIImageView() の部分に赤下線と下記のエラー文が表示されました。調べてみましたがよく分かりませんでした。
解決方法をご存知の方がいらっしゃいましたらご教授ください。よろしくお願いします。

発生している問題・エラー

Thread 1: EXC_BAD_ACCESS (code=2, address=0x16b077e98)

該当するソースコード

class MyAccountViewController: UITableViewController {


    let iconImageView = UIImageView()
    

    override func viewDidLoad() {

        super.viewDidLoad()
        
        setupSubviews()
    }
    

    func setupSubviews() {
        
        let defaultIconImage = UIImage(systemName: "person")
        iconImageView.contentMode = .scaleAspectFit
        iconImageView.image = defaultIconImage
        
        view.addSubview(iconImageView)
        
        iconImageView.snp.makeConstraints {
            
            $0.width.equalToSuperview()
            $0.height.equalTo(view.frame.width)
            $0.top.equalToSuperview()
            $0.leading.equalToSuperview()
        }
        
    }

}
0

1Answer

お力になれると思いますが、下記2点をお願いできますか。

  1. エラーが表示されているウィンドウのスクリーンショットを貼ってほしい。

  2. AppDelegateSceneDelegateクラスのコードも貼ってほしい。


追伸;

↓このサイトで説明されている内容は、実施済みでしょうか?

0Like

Comments

  1. @KAinone

    Questioner

    ご返答いただきありがとうございます。
    Storyboardを使わない設定に関しては実施済みでしたが、貼っていただいたサイトを拝見したところ、書き方が少し違うところがあったので変更してみました。すると、元のエラーがなくなり(?)別のエラーが出てしまいました、、、
    関係があるか分かりませんが、変更前後のスクリーンショットとSceneDelegateのコードを記載します。
    スクリーンショットや提供情報に不備・不足がありましたらお手数ですがご連絡いただけると幸いです。よろしくお願いします。

    <変更前>エラーが表示されているウィンドウのスクリーンショット
    Screenshot 2023-11-13 at 16.23.25.png

    <変更前>SceneDelegate

    import UIKit
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            
            guard let _ = (scene as? UIWindowScene) else { return }
            
            if let windowScene = scene as? UIWindowScene {
                
                let window = UIWindow(windowScene: windowScene)
                window.makeKeyAndVisible()
                
                window.rootViewController = TabBarController()
                
                self.window = window
            }
    
        }
    
        func sceneDidDisconnect(_ scene: UIScene) {
    
        }
    
        func sceneDidBecomeActive(_ scene: UIScene) {
            
        }
    
        func sceneWillResignActive(_ scene: UIScene) {
            
        }
    
        func sceneWillEnterForeground(_ scene: UIScene) {
            
        }
    
        func sceneDidEnterBackground(_ scene: UIScene) {
            
        }
    
    }
    

    <変更後>エラーが表示されているウィンドウのスクリーンショット
    Screenshot 2023-11-13 at 16.43.51.png

    <変更後>SceneDelegate

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            
            guard let windowScene = (scene as? UIWindowScene) else { return }
            
            window = UIWindow(frame: windowScene.coordinateSpace.bounds)
            window?.windowScene = windowScene
            window?.rootViewController = TabBarController()
            window?.makeKeyAndVisible()
        }
    
  2. 68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3633363031342f31353566616138342d613866392d626566382d316538662d3233363433323238383035322e706e67.png

    ↑右下の赤枠で囲ったエリアの縦幅を広げて、できれば実行開始からすべての出力内容が見えるようにして、再度スクショを貼ってください。すべてが表示しきれない程いろいろ出力されているならば、ここのテキストをすべてコピーペーストでコードブロックに貼ってください。

    確認ですが、このアプリのメインのViewはTabBarControllerで、MyAccountViewController が表示される前に落ちているのでしょうか?
    シミュレーターにTabBarのViewは表示されていますか?


    SceneDelegateの変更は.coordinateSpace.boundsの有無だけです。他の行は書き方に差がありますが、本質的には同じです。


    追伸;

    変更前のスクショをよく見ると、最初にコードを掲示されたviewDidLoadと内容が異なっています。
    最新のviewDidLoadのコードを貼ってください。MyAccountViewController.swift全体でも構いません。

  3. @KAinone

    Questioner

    このアプリは、サインアップしていない場合はWelcomViewController、サインインしている場合はHomeViewController、アカウント情報の登録が済んでいない場合はEditViewController、というようにTabBarController(root)で調べて、結果に応じた画面遷移をするようにしています。
    MyAccountViewControllerTabBarControllerから直接遷移することはなく、HomeViewControllerにあるUIButtonを押すことで遷移するようになっています。

    現在シミュレーターを起動すると、HomeViewControllerが表示されるようになっています。
    このときのデバッグとシミュレーターのスクリーンショットを添付します。
    FirebaseのAuthenticationからユーザーを削除してシミュレーターを立ち上げていますが、過去にシミュレーターで実行したサインインの情報がキャッシュで残っている?のか、サインインしていると判断されているため、この結果になっていると思っています。
    Erase All Content and Settingsをしても変わりませんが、時間が経つと消えていることがあります、、、

    クラッシュしてしまう原因はレイアウトが干渉しているからかもしれません。
    ファイルが30もあるので大変ですが、その点を見直してみます。

    <デバッグ>
    Screenshot 2023-11-13 at 19.13.33.png

    <シミュレーター>
    Screenshot 2023-11-13 at 19.14.30.png

    TabBarController

    import UIKit
    import FirebaseAuth
    import FirebaseFirestore
    
    
    
    class TabBarController: UITabBarController {
        
    
        override func viewDidLoad() {
            
            super.viewDidLoad()
            
            setupSubViews()
            
            selectedIndex = 0
        }
        
        
        override func viewWillAppear(_ animated: Bool) {
            
            super.viewWillAppear(animated)
            
            setupUser()
        }
        
        
        func setupSubViews() {
            
            let home = HomeViewController()
            let talkRoom = TalkroomViewController()
            
            home.tabBarItem = UITabBarItem(title: "Home", image: UIImage(systemName: "house"), tag: 0)
            talkRoom.tabBarItem = UITabBarItem(title: "Message", image: UIImage(systemName: "message"), tag: 1)
            
            viewControllers = [home, talkRoom]
        }
        
        
        func setupUser() {
            
            if Auth.auth().currentUser == nil {
                
                let welcomeViewController = WelcomeViewController()
                welcomeViewController.modalPresentationStyle = .fullScreen
                
                self.present(welcomeViewController, animated: true, completion: nil)
                
            } else {
                
                let uid = Auth.auth().currentUser?.uid
                let userRef = Firestore.firestore().collection(Const.UserPath).document(uid!)
                
                userRef.getDocument { (document, error) in
                    
                    if error != nil {
                        
                        let editViewController = EditViewController()
                        editViewController.modalPresentationStyle = .fullScreen
                        
                        self.present(editViewController, animated: true, completion: nil)
                    }
                    
                }
                    
            }
            
        }
        
    
    }
    
  4. 上のデバッグのメッセージだけなら、落ちる要因ではないと思います。

    TabBarController ではなく、MyAccountViewControllerviewDidLoad全体のコードを見たかったですが、ご自身で見直されるということですので、一旦、静観することにします。
    また、何かありましたら、Q&A上げてください。

  5. @KAinone

    Questioner

    デバッグのメッセージは落ちる要因じゃないのですね。。。
    頑張って修正してみます!
    もし何か改善点などありましたらお聞かせ願いたいので一応MyAccountViewControllerのコードを載せておきます。
    理解が及ばずお手数おかけし申し訳ありません。具体的な質問ができるよう精進します。

    import UIKit
    import SnapKit
    import PKHUD
    import FirebaseAuth
    import FirebaseFirestore
    import FirebaseStorage
    import FirebaseStorageUI
    
    
    
    class MyAccountViewController: UITableViewController, MyAccountViewCellDelegate {
        
        
        let iconImageView = UIImageView()
        let myAccountViewCell = MyAccountViewCell()
        
        var artistName: String!
        var birthday: String!
        
        override func viewDidLoad() {
            
            super.viewDidLoad()
            
            tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
            tableView.delaysContentTouches = false
            tableView.backgroundColor = .clear
            
            tableView.delegate = self
            tableView.dataSource = self
            
            setupSubviews()
            
            tableView.register(MyAccountViewCell.self, forCellReuseIdentifier: "myAccountViewCell")
        }
        
        
        override func viewWillAppear(_ animated: Bool) {
            
            super.viewWillAppear(animated)
            
            getData()
            togglePostSwitch()
            birthdayToAge()
        }
        
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            
            return 1
        }
        
        
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
            let cell = tableView.dequeueReusableCell(withIdentifier: "myAccountViewCell") as! MyAccountViewCell
            
            cell.myAccountViewCellDelegate = self
            
            return cell
        }
        
        
        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            
            let screenWidth = UIScreen.main.bounds.width
            let screenHeight = UIScreen.main.bounds.height
            
            return screenWidth + screenHeight - 95
        }
        
        
        override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
            
            return false
        }
        
        func setupSubviews() {
            
            let defaultIconImage = UIImage(systemName: "person")
            iconImageView.contentMode = .scaleAspectFit
            iconImageView.image = defaultIconImage
            
            view.addSubview(iconImageView)
            
            iconImageView.snp.makeConstraints {
                
                $0.width.equalToSuperview()
                $0.height.equalTo(view.frame.width)
                $0.top.equalToSuperview()
                $0.leading.equalToSuperview()
            }
            
        }
        
        
        func getData() {
            
            let uid = Auth.auth().currentUser?.uid
            let imageRef = Storage.storage().reference().child(Const.ImagePath).child(uid! + ".jpg")
            
            iconImageView.sd_imageIndicator = SDWebImageActivityIndicator.gray
            iconImageView.sd_setImage(with: imageRef)
            
            let userRef = Firestore.firestore().collection(Const.UserPath).document(uid!)
            //let defaultIconImage = UIImage(systemName: "person")
            
            userRef.getDocument { (document, error) in
                
                if error != nil {
                    
                    HUD.flash(.labeledError(title: "Error.", subtitle: ""), delay: 1)
                }
                
                if let document = document, document.exists {
                    
                    let userDic = document.data()
                    
                    self.myAccountViewCell.baseLabel.text = userDic!["myBase"] as? String
                    self.myAccountViewCell.partLabel.text = userDic!["myPart"] as? String
                    self.myAccountViewCell.genreLabel.text = userDic!["myGenre"] as? String
                    self.myAccountViewCell.ivtPartLabel.text = userDic!["ivtPart"] as? String
                    self.myAccountViewCell.ivtTitleLabel.text = userDic!["ivtTitle"] as? String
                    self.myAccountViewCell.ivtContentLabel.text = userDic!["ivtContent"] as? String
                    self.myAccountViewCell.introductionLabel.text = userDic!["introduction"] as? String
                    self.myAccountViewCell.urlLabel.text = userDic!["url"] as? String
                    
                    if let birthday = userDic!["birthday"] as? String {
                        
                        let displayName = Auth.auth().currentUser?.displayName
                        let dateFormatter = DateFormatter()
                        let date = dateFormatter.date(from: birthday)
                        let components = Calendar.current.dateComponents(in: TimeZone.current, from: date!)
                        let year = components.year
                        let month = components.month
                        let day = components.day
                        var ageInt: Int
                        let birthdate = DateComponents(year: year, month: month, day: day)
                        let calendar = Calendar.current
                        let now = calendar.dateComponents([.year, .month, .day], from: Date())
                        let ageComponents = calendar.dateComponents([.year], from: birthdate, to: now)
                        ageInt = ageComponents.year!
                        let ageStr = String(ageInt)
                        let nameAge = displayName! + " " + ageStr
                        
                        self.myAccountViewCell.nameAgeLabel.text = nameAge
                    }
                    
                } else {
                    
                    HUD.flash(.labeledError(title: "No Documents.", subtitle: ""), delay: 1)
                }
                
            }
            
        }
        
        
        func togglePostSwitch() {
            
            let uid = Auth.auth().currentUser?.uid
            let postRef = Firestore.firestore().collection(Const.PostPath).document(uid!)
            
            postRef.getDocument { (document, error) in
                
                if error != nil {
                    
                    HUD.flash(.labeledError(title: "Error.", subtitle: ""), delay: 1)
                }
                
                if let document = document, document.exists {
                    
                    self.myAccountViewCell.postSwitch.isOn = true
                    
                } else {
                    
                    self.myAccountViewCell.postSwitch.isOn = false
                }
                
            }
            
        }
        
        func birthdayToAge() {
            
            let dateFormatter = DateFormatter()
            let date = dateFormatter.date(from: birthday)
            let components = Calendar.current.dateComponents(in: TimeZone.current, from: date!)
            let year = components.year
            let month = components.month
            let day = components.day
            
            var ageInt: Int
            let birthdate = DateComponents(year: year, month: month, day: day)
            let calendar = Calendar.current
            let now = calendar.dateComponents([.year, .month, .day], from: Date())
            let ageComponents = calendar.dateComponents([.year], from: birthdate, to: now)
            ageInt = ageComponents.year!
            let ageStr = String(ageInt)
            let nameAge = artistName + " " + ageStr
            
            myAccountViewCell.nameAgeLabel.text = nameAge
        }
        
        func backButtonDelegate() {
            
            self.dismiss(animated: true)
        }
        
        func settingButtonDelegate() {
            
            let settingViewController = SettingViewController()
            settingViewController.modalPresentationStyle = .fullScreen
            
            self.present(settingViewController, animated: true, completion: nil)
        }
    
    }
    
    

    追伸

    すみません、追伸に気付きませんでした。
    最初に掲示したコードはエラーと関係ないと勝手に判断した部分を排除していました。
    こちらが最初から変わらず最新のコードです。

Your answer might help someone💌