在 segue 和 dismiss 期间崩溃

Crashing during segue and dismiss

我有一个问题,我的应用程序在 tableViewController 的 segue 期间崩溃

import UIKit
import MapKit
import CoreLocation

class CourseClass: UITableViewController, CLLocationManagerDelegate, MKMapViewDelegate {

    @IBOutlet weak var map: MKMapView!

    struct User {

        var name: String
        var images: UIImage
        var coordinate: (Double, Double)
        var type: String
    }

    /* var place = ["Caffè Spagar", "Duks", "Posta station", "Barnum", "Elephant Club", "Cinema", "Space", "Andromeda", "Rodolf", "Devil Chair"] */

    var rows = 0
    var users = [User]()

    let CS = User(name: "Caffè Spagar", images: UIImage(named: "Caffè Spagar.png")! , coordinate:(12345,54678), type: "Pub")
    let D = User(name: "Duks", images: UIImage(named: "Duks.png")! , coordinate:(13345,54128), type: "Shopping")
    let PS = User(name: "Posta station", images: UIImage(named: "Posta station.png")! , coordinate:(18795,34556), type: "Resturant")
    let B = User(name: "Barnum", images: UIImage(named: "Barnum.png")! , coordinate:(46655,43554), type: "Pub")
    let EC = User(name: "Elephant Club", images: UIImage(named: "Elephant Club.png")! , coordinate:(12325,21435), type: "Disco")
    let C = User(name: "Cinema", images: UIImage(named: "Cinema.png")! , coordinate:(11235,12343), type: "Cinema")
    let S = User(name: "Space", images: UIImage(named: "Space.png")! , coordinate:(12345,66432), type: "Cinema")
    let A = User(name: "Andromeda", images: UIImage(named: "Andromeda.png")! , coordinate:(64545,23443), type: "Sport")
    let R = User(name: "Rodolf", images: UIImage(named: "Rodolf.png")! , coordinate:(64545,34358), type: "Shopping")
    let DC = User(name: "Devil Chair", images: UIImage(named: "Devil Chair.png")! , coordinate:(56656,54678), type: "Shopping")

    override func viewDidLoad() {
        super.viewDidLoad()

        map.showsUserLocation = true
        map.delegate = self

        users.append(CS)
        users.append(D)
        users.append(PS)
        users.append(B)
        users.append(EC)
        users.append(C)
        users.append(S)
        users.append(A)
        users.append(R)
        users.append(DC)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        insertRowsMode3()
    }

    func insertRowsMode2() {

        for i in 0..<users.count {
            insertRowMode2(ind: i, usr: users[i])
        }

    }

    func insertRowMode2(ind:Int,usr:User) {

        let indPath = IndexPath(row: ind, section: 0)

        rows = ind + 1
        tableView.insertRows(at: [indPath], with: .right)
    }

    func insertRowsMode3() {

        rows = 0

        insertRowMode3(ind: 0)
    }

    func insertRowMode3(ind:Int) {
        let indPath = IndexPath(row: ind, section: 0)
        rows = ind + 1
        tableView.insertRows(at: [indPath], with: .right)

        guard ind < users.count-1 else { return }
        DispatchQueue.main.asyncAfter(deadline: .now()+0.15) {

            self.insertRowMode3(ind: ind+1)
        }
    }    

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return rows
    }

    public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell

      let user = users[indexPath.row]

        cell.myImage.image = user.images
        cell.myLabel.text = user.name
        cell.myTypeLabel.text = user.type

    /*  cell.myImage.image = UIImage(named: (place[indexPath.row] + ".png"))
        cell.myLabel.text = place[indexPath.row]
    */

        return (cell)
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

       performSegue(withIdentifier: "goToLast" , sender: users[indexPath.row])

    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
    }

    @IBAction func mapTapped(_ sender: Any) {

    let userLocation = map.userLocation

    let region = MKCoordinateRegionMakeWithDistance((userLocation.location?.coordinate)!,2000,2000)       
    map.setRegion(region, animated: true)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goToLast" {

        guard let vc = segue.destination as? FinalClass else { return }

        let guest = segue.destination as! FinalClass

              guest.local = sender as! String

             guest.localImage = UIImage(named: (sender as! String) + ".png")!     
            guest.localType = sender as! String            
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }    
}

正是在这个函数中

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "goToLast" {           
        guard let vc = segue.destination as? FinalClass else { return }

        let guest = segue.destination as! FinalClass

              guest.local = sender as! String

             guest.localImage = UIImage(named: (sender as! String) + ".png")!            
            guest.localType = sender as! String       
    }
}

问题是

Could not cast value of type 'Myapp.CourseClass.User' to 'Swift.String'.

同样在遇到这个问题之前,当我关闭下一个场景回到这里时应用程序崩溃了。有人知道如何调整我的代码以使其工作吗?

您正在发送用户 Class,然后将用户 Class 转换为字符串

试试这个

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "goToLast" {

    guard let vc = segue.destination as? FinalClass else { return }

    let guest = segue.destination as! FinalClass
         if let user = sender as? User {

          guest.local = user.local

         guest.localImage = user.image

        guest.localType = user.localType
     }


    }
}
guest.local = sender as! String

             guest.localImage = UIImage(named: (sender as! String) + ".png")!

            guest.localType = sender as! String

问题似乎出在这里,请尝试将 "sender" 的类型设为 Any,我认为它属于用户类型,导致崩溃的原因是

Could not cast value of type 'Myapp.CourseClass.User' to 'Swift.String'

这意味着您正在强制将用户类型对象转换为字符串。

可以将 khalid 的答案固定为

 if let user = sender as? User {

          guest.local = user.local

         guest.localImage = user.image

        guest.localType = user.localType
     }

找到确切崩溃原因的另一种干净的调试方法可以是:

  • 进入 BreakPoint Navigator 在 Xcode 左侧的 Navigator 选项卡中。

  • 创建一个 All Exception Breakpoint,如下图所示, 当您使用 运行 应用程序时,将在确切的崩溃行停止您的代码 调试开启。