当前位置:  开发笔记 > 编程语言 > 正文

快速致命的错误:'试试!' 表达式意外地引发了一个错误:错误Domain = NSCocoaErrorDomain Code = 3840"垃圾结束时".

如何解决《快速致命的错误:'试试!'表达式意外地引发了一个错误:错误Domain=NSCocoaErrorDomainCode=3840"垃圾结束时".》经验,为你挑选了1个好方法。

我的swift程序一直出现这个错误,我使用PHP和MySQL作为数据库.我将数据从数据库显示到tableview.它以前工作但经过几次运行到模拟器后,我一直有同样的错误

class Home: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var btnaddclass: UIButton!
@IBOutlet var tableView: UITableView!
   var values: NSArray = []

func get(){
    let url = NSURL(string: "http://localhost/show_db.php")
    let data = NSData(contentsOf: url! as URL)
    values = try! JSONSerialization.jsonObject(with: data! as Data, options:JSONSerialization.ReadingOptions.mutableContainers)as! NSArray
    tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return values.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SpecialCell
    let maindata = values[indexPath.row] as! [String:AnyObject]

    cell.Lblclasstitle.text = maindata["class_title"] as? String
    cell.Lblschool.text = maindata["school"] as? String
    cell.Lblsubject.text = maindata["subject"] as? String
    return cell
}
   override func viewDidLoad() {
    self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
    get()


}
override func viewWillAppear(_ animated: Bool) {
    self.tableView.reloadData()
}
}

Guillermo Al.. 7

正如其他一些答案所指出的那样,问题在于您正在强制进行JSON反序列化,并假设它始终在100%的时间内正常工作.这几乎总是不太好的选择.有两种方法可以解决这个问题:

1)使用试试?代替

如果您尝试执行的语句失败,那么这将是一个很好的选择,然后您将获得nil然后可以基于此做一些事情.例如,您可以将get()函数更改为:

func get(){
    //remove NS prefix and unwrap optional
    guard let url = URL(string: "http://localhost/show_db.php") else { return }

    //remove ! from url and unwrap optional
    guard let data = try? Data(contentsOf: url) else { return }

    //try to deserialize. The return value is of type Any
    guard let deserializedValues = try? JSONSerialization.jsonObject(with: data) else { return }

    //Convert to array of dictionaries
    guard let arrayOfDictionaryValues = deserializedValues as? [[String:String]] else { return }

    //If you make it here, that means everything is ok
    values = arrayOfDictionaryValues

    tableView.reloadData()
}

请注意,每个保护语句都为您提供了执行某些操作并返回的机会.也许您想显示一条消息,指出存在网络错误.

2)使用do try catch块.

我想用try?更适合你的情况但是在某些情况下尝试catch块是合适的.例如:

func getWithErrorHandling() {
    guard let url = URL(string: "http://localhost/show_db.php") else { return }

    do {
        let data = try Data(contentsOf: url)
        let deserializedValues = try JSONSerialization.jsonObject(with: data)
        guard let arrayOfDictionaryValues = deserializedValues as? [[String:String]] else { return }
        values = arrayOfDictionaryValues
    } catch {
        //You should separate the different catch blocks to handle the different types of errors that occur
        print("There was an error")
    }
}

您可以对整体方法进行其他改进,但由于您是初学者(如您所述),最好一次学习一件事.

此外,正如其他人所提到的,您不应该从主线程获取数据.请改用URLSession.这篇文章就是一个很好的例子:

正确解析Swift 3中的JSON



1> Guillermo Al..:

正如其他一些答案所指出的那样,问题在于您正在强制进行JSON反序列化,并假设它始终在100%的时间内正常工作.这几乎总是不太好的选择.有两种方法可以解决这个问题:

1)使用试试?代替

如果您尝试执行的语句失败,那么这将是一个很好的选择,然后您将获得nil然后可以基于此做一些事情.例如,您可以将get()函数更改为:

func get(){
    //remove NS prefix and unwrap optional
    guard let url = URL(string: "http://localhost/show_db.php") else { return }

    //remove ! from url and unwrap optional
    guard let data = try? Data(contentsOf: url) else { return }

    //try to deserialize. The return value is of type Any
    guard let deserializedValues = try? JSONSerialization.jsonObject(with: data) else { return }

    //Convert to array of dictionaries
    guard let arrayOfDictionaryValues = deserializedValues as? [[String:String]] else { return }

    //If you make it here, that means everything is ok
    values = arrayOfDictionaryValues

    tableView.reloadData()
}

请注意,每个保护语句都为您提供了执行某些操作并返回的机会.也许您想显示一条消息,指出存在网络错误.

2)使用do try catch块.

我想用try?更适合你的情况但是在某些情况下尝试catch块是合适的.例如:

func getWithErrorHandling() {
    guard let url = URL(string: "http://localhost/show_db.php") else { return }

    do {
        let data = try Data(contentsOf: url)
        let deserializedValues = try JSONSerialization.jsonObject(with: data)
        guard let arrayOfDictionaryValues = deserializedValues as? [[String:String]] else { return }
        values = arrayOfDictionaryValues
    } catch {
        //You should separate the different catch blocks to handle the different types of errors that occur
        print("There was an error")
    }
}

您可以对整体方法进行其他改进,但由于您是初学者(如您所述),最好一次学习一件事.

此外,正如其他人所提到的,您不应该从主线程获取数据.请改用URLSession.这篇文章就是一个很好的例子:

正确解析Swift 3中的JSON

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有